Brandon's Tinkerings
brandon_wiki
http://brandon.penglase.net/index.php?title=Main_Page
MediaWiki 1.40.1
first-letter
Media
Special
Talk
User
User talk
Brandon's Tinkerings
Brandon's Tinkerings talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Main Page
0
1
1
2012-05-30T17:15:08Z
MediaWiki default
0
wikitext
text/x-wiki
'''MediaWiki has been successfully installed.'''
Consult the [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
b7a3846f2c55072191227d89a3204fe379288fee
2
1
2012-05-30T18:31:55Z
Bpenglase
1
/* Getting started */
wikitext
text/x-wiki
'''MediaWiki has been successfully installed.'''
Consult the [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
* [Special:UserRights]
e90be915c41457426f7f5f1b4d48aa9d2bfb7e75
3
2
2012-05-30T18:48:07Z
Bpenglase
1
Replaced content with "''' Welcome. '''"
wikitext
text/x-wiki
''' Welcome. '''
6c2ba7aaa26c48242adcfb6766feba8c4dc77643
5
3
2012-05-31T00:53:46Z
Bpenglase
1
wikitext
text/x-wiki
''' Welcome. '''
Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work.
* Computer Related Prodding
* Network Wrangling
* Dabbling in Electronics
bbfc9c932f18949aed92dd067a8da74d93f686a2
6
5
2012-05-31T00:55:58Z
Bpenglase
1
wikitext
text/x-wiki
''' Welcome. '''
Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work.
* [[Computer Related Prodding]]
* [[Network & Systems Wrangling]]
* [[Dabbling in Electronics]]
1f01972f3a2972786a957be902f8add290854595
MediaWiki:Sidebar
8
2
4
2012-05-30T18:54:54Z
Bpenglase
1
Created page with " * navigation ** mainpage|mainpage-description ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help * SEARCH * TOOLBOX"
wikitext
text/x-wiki
* navigation
** mainpage|mainpage-description
** recentchanges-url|recentchanges
** randompage-url|randompage
** helppage|help
* SEARCH
* TOOLBOX
3b3992950fca6cf2b1c804b675d8a6e4c6f63c8d
Computer Related Prodding
0
3
7
2012-05-31T01:08:49Z
Bpenglase
1
Created page with "* [[The World According to Apple]] - Ways I have found to get OS X/iOS to function in the "Enterprise" world, typically with 3rd party software. * Breaking Windows - Different..."
wikitext
text/x-wiki
* [[The World According to Apple]] - Ways I have found to get OS X/iOS to function in the "Enterprise" world, typically with 3rd party software.
* Breaking Windows - Different things I have found building Windows images and supporting Windows machines
06c95873247bbeb27f7bf6e7006973c51505f749
The World According to Apple
0
4
8
2012-05-31T01:12:01Z
Bpenglase
1
Created page with "* [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images."
wikitext
text/x-wiki
* [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images.
386c8f5bd83f11c9535f79e31b35a02ffb997d18
Getting *nix to Netboot Macs
0
5
9
2012-05-31T01:13:08Z
Bpenglase
1
Created page with "<syntaxhilight lang="bash"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLB..."
wikitext
text/x-wiki
<syntaxhilight lang="bash">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Ask for these options from the client
if (option dhcp-message-type = 1) {
# On DHCPDiscover Message(s)
# Tell the client, via selected boot image (08:04:), which image we're preferring as default (81:00:00:89)
option vendor-class-identifier "AAPLBSDPC";
option vendor-encapsulated-options 08:04:81:00:00:89; # bsdp option 8 (length 04) -- selected image id;
} elsif (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
#-- Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/ipxe.efi";
next-server 10.0.3.2;
option root-path = "http://boot.neltia.net/ipxe.efi";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
filename "DSRBoot.img";
next-server 10.0.3.2;
option root-path = "http://osx-server.boot.neltia.net/DSRBoot.img";
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhilight>
2ffb9cf6e5419bc6066e9c5b083ec74aa53bb8e3
10
9
2012-05-31T01:23:15Z
Bpenglase
1
wikitext
text/x-wiki
<syntaxhighlight lang="bash">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Ask for these options from the client
if (option dhcp-message-type = 1) {
# On DHCPDiscover Message(s)
# Tell the client, via selected boot image (08:04:), which image we're preferring as default (81:00:00:89)
option vendor-class-identifier "AAPLBSDPC";
option vendor-encapsulated-options 08:04:81:00:00:89; # bsdp option 8 (length 04) -- selected image id;
} elsif (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
#-- Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/ipxe.efi";
next-server 10.0.3.2;
option root-path = "http://boot.neltia.net/ipxe.efi";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
filename "DSRBoot.img";
next-server 10.0.3.2;
option root-path = "http://osx-server.boot.neltia.net/DSRBoot.img";
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
538d05ff4e4e1acca307b8d83195bd4e40ec5925
11
10
2012-05-31T01:37:06Z
Bpenglase
1
wikitext
text/x-wiki
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Ask for these options from the client
if (option dhcp-message-type = 1) {
# On DHCPDiscover Message(s)
# Tell the client, via selected boot image (08:04:), which image we're preferring as default (81:00:00:89)
option vendor-class-identifier "AAPLBSDPC";
option vendor-encapsulated-options 08:04:81:00:00:89; # bsdp option 8 (length 04) -- selected image id;
} elsif (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
#-- Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/ipxe.efi";
next-server 10.0.3.2;
option root-path = "http://boot.neltia.net/ipxe.efi";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
filename "DSRBoot.img";
next-server 10.0.3.2;
option root-path = "http://osx-server.boot.neltia.net/DSRBoot.img";
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
6d7a342f1fcd47a5d55b3569ed315be34e8f9e1c
12
11
2012-05-31T02:09:59Z
Bpenglase
1
wikitext
text/x-wiki
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
a4cca3876d1a0026ec8b433af0bee2b02a62055a
13
12
2012-05-31T03:17:51Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html http://www.dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
811061bbed2765ba473f8965c7ca0904065b6490
14
13
2012-05-31T03:23:14Z
Bpenglase
1
/* Resources Used to Complete this */
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
5152e0f8c39f659c3e6c68323219cff84c923e56
15
14
2012-05-31T03:23:32Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
== Fin ==
I have learned more about BSDP then I ever wanted to know :)
34341541944094eb312a1916b26f501a089290df
16
15
2012-05-31T03:26:53Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
== Fin ==
* I have learned more about BSDP then I ever wanted to know :)
* I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox.
77ff8e6ab761af8144ce2563350d141e1604e0ad
17
16
2012-05-31T12:45:13Z
Bpenglase
1
Added line about posting to OSXDeployment
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
== Fin ==
* Once [http://osxdeployment.com/wiki/Main_Page OSXDeployment.com] is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.
* I have learned more about BSDP then I ever wanted to know :)
* I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox.
3bc8e3d96b85b8c08df36f7df7257dd7e0a39459
Network & Systems Wrangling
0
6
18
2012-09-28T00:06:21Z
Bpenglase
1
Added link for FreeRADIUS config
wikitext
text/x-wiki
[[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users. Including but not limited to: WPA2-Enterprise and EAPoL (Wireless and Wired authentication)
2493abd2c00b8d721fbc32d98b7ceacfc80e71a8
19
18
2012-09-28T00:07:18Z
Bpenglase
1
Corrected wording on FreeRADIUS line.
wikitext
text/x-wiki
[[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
7ef89dc110426c02ea46e1ac4d98b665f99ea211
34
19
2012-09-29T02:26:38Z
Bpenglase
1
Added sections for cisco switches/aps
wikitext
text/x-wiki
[[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
[[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
[[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
f0ea2c97d2b888dcd2d82e98d97c9bbe5d72a288
35
34
2012-09-29T02:27:11Z
Bpenglase
1
wikitext
text/x-wiki
[[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
[[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
[[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
1dfd9f896f9f9bdabed0e29bf74d6345f4f072a9
36
35
2012-09-29T02:27:46Z
Bpenglase
1
Formatting
wikitext
text/x-wiki
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
* [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
* [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
25d4d61089732d63aed75c457a8f494340ec6f16
46
36
2012-10-13T01:37:13Z
Bpenglase
1
Added PXE Boot
wikitext
text/x-wiki
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
* [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
* [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
* [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics.
6e45470dd6c00fffc0a29b0eb33a75693fe0367d
Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP
0
7
20
2012-09-28T02:37:55Z
Bpenglase
1
Initial submit of the FreeRADIUS config page
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup FreeRADIUS to do 802.1x authentication. Why am I doing another? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up another page here. This was also expedited by user in the #FreeRADIUS channel looking to do the same, but as I as posting configs, it wasn't helping.
So, without further ado, I give you my guide on setting up FreeRADIUS pulling it's information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from (http://www.cacert.org CACert). I do recommend them, especially if you can get assured.
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* FreeRADIUS was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
* SSL Cert from CACert (needs to be known who the CA is when configuring it).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
9b45d6d95a75a984f98c26696b3b239cdc8c72ba
21
20
2012-09-28T02:57:20Z
Bpenglase
1
Other changes, included LDAP config, caveats, etc.
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #FreeRADIUS channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** The LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless only, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured.
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
0aea01758acd62adb712b80954e8f0238460468e
22
21
2012-09-28T02:59:12Z
Bpenglase
1
/* Intro */ Corrected FreeRADIUS irc channel case.
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** The LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless only, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured.
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
7eddf5c8e888b5491252e4f321744ae5f3feeb95
23
22
2012-09-28T02:59:51Z
Bpenglase
1
/* What does this page assume? */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless only, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured.
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
26191620edf215286fbd42e87227472b551d7610
24
23
2012-09-28T03:00:13Z
Bpenglase
1
/* What does this page assume? */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured.
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
752f4dcdc370eb8f24e6f7f00b3f62c04400e74e
25
24
2012-09-28T03:02:10Z
Bpenglase
1
/* What does this page assume? */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me.
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
6bde6a83938a463e8018e2f5c3ad632a2a920fb8
26
25
2012-09-28T03:03:01Z
Bpenglase
1
/* My testing environment */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
53bff4d109cd57a48dd455fefdca9aa50476243f
27
26
2012-09-28T03:03:25Z
Bpenglase
1
/* clients.conf */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32.
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
afa5a41583dc4802ec8eb1c32ee9ab189de041af
28
27
2012-09-28T03:04:38Z
Bpenglase
1
/* clients.conf */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc).
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* Added: checkItem Cleartext-Password userPassword
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
d97a00838adeb496022c23a614f35d0a3c83ced4
29
28
2012-09-28T03:05:37Z
Bpenglase
1
/* ldap.attrmap */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc).
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* checkItem Cleartext-Password userPassword -- Added at bottom
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
8e7122d40b1ff01f8369b0fc3550611122a822cf
30
29
2012-09-28T03:07:39Z
Bpenglase
1
/* modules/ldap */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc).
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* checkItem Cleartext-Password userPassword -- Added at bottom
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
*** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP)
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
e5435c9f32d1958f6db0206aa0199bf6035c19d5
31
30
2012-09-28T03:20:12Z
Bpenglase
1
added a lot, and resources.
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc).
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* checkItem Cleartext-Password userPassword -- Added at bottom
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
*** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP)
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
** As such, I highly recommend doing TLS on LDAP, since otherwise you might end up with passwords going over the wire in clear-text.
* I know some of the stuff in LDAP isn't fully clear, or some of the more advanced stuff like VLAN assignment. I'll try to clear these up later, but for right now, this should get you up and going.
== Resources used ==
* Sadly I set the majority of this up a long time ago, but I do seem to have some bookmarks, so I'll throw some of them here. Otherwise, I only used one recently from the FreeRADIUS mailing list.
* http://vuksan.com/linux/dot1x/802-1x-LDAP.html -- Good guide, also covers setting up OpenLDAP and it's ACLs, and device setup.
* http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius
* [http://wiki.freeradius.org/Home The FreeRADIUS Wiki]
* http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg48720.html -- Email through bookmarked.
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. Sometimes I am in the #freeradius channel, sometimes not, but I am usually connected.
* http://lists.freeradius.org/pipermail/freeradius-users/2012-January/058185.html -- This thread, specially this post to get the Dynamic VLAN assignment working.
9b9922edac4b344ec220a7a628c78af098564195
32
31
2012-09-28T03:22:47Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc).
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* checkItem Cleartext-Password userPassword -- Added at bottom
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
*** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP)
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
** As such, I highly recommend doing TLS on LDAP, since otherwise you might end up with passwords going over the wire in clear-text.
* I know some of the stuff in LDAP isn't fully clear, or some of the more advanced stuff like VLAN assignment. I'll try to clear these up later, but for right now, this should get you up and going.
== Resources used ==
* Sadly I set the majority of this up a long time ago, but I do seem to have some bookmarks, so I'll throw some of them here. Otherwise, I only used one recently from the FreeRADIUS mailing list.
* http://vuksan.com/linux/dot1x/802-1x-LDAP.html -- Good guide, also covers setting up OpenLDAP and it's ACLs, and device setup.
* http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius
* [http://wiki.freeradius.org/Home The FreeRADIUS Wiki]
* http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg48720.html -- Email thread bookmarked.
* http://lists.freeradius.org/pipermail/freeradius-users/2012-January/058185.html -- This thread, specially this post to get the Dynamic VLAN assignment working.
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. Sometimes I am in the #freeradius channel, sometimes not, but I am usually connected.
274917adf79dafc932c896ad24aff642d3aa7189
33
32
2012-09-28T03:25:23Z
Bpenglase
1
/* Resources used */
wikitext
text/x-wiki
== Intro ==
You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open.
Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it.
This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping.
This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment)
So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend.
== What does this page assume? ==
* You have a working OpenLDAP setup.
** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP.
** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time.
** Passwords are stored in plain text
** My LDAP tree is setup as such:
*** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name)
**** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same
**** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs
** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical.
* You have configured your end devices (or will once FreeRADIUS is setup).
** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based.
* You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS).
== My testing environment ==
* Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine)
** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board
* freeradius-2.1.11-r1 was emerged with the following USE line:
** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'.
** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius
* SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there).
== The Files ==
* All files are referenced from /etc/raddb/
=== clients.conf ===
* Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc).
<syntaxhighlight lang="bash">
client 10.0.3.64/28 {
secret = testing1234
}
</syntaxhighlight>
=== eap.conf ===
* Under EAP {}:
** default_eap_type = peap
** Under TLS {}:
*** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate.
*** pem_file_type = yes -- This is an addition
*** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above
*** cadir = /etc/ssl/certs -- since CACert is included in the system CAs
*** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache)
*** private_key_file = ${certdir}/<domain>_wildcard.key
*** certificate_file = ${certdir}/<domain>_wildcard.crt
*** CA_file = ${cadir}/cacert.org.pem
*** #CA_path = ${cadir} -- Commented out, maybe this is fine?
** Under peap {}:
*** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this
=== ldap.attrmap ===
* checkItem Cleartext-Password userPassword -- Added at bottom
** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU.
=== modules/ldap ===
* Under ldap {}:
** server = "server.domain.com" -- set to your LDAP Server
** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below
** password = "MyradiusUserPassword"
** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout.
** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter.
** Under tls {}:
*** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it.
*** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs.
*** require_cert = "demand" -- Uncomment
*** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP)
** access_attr_used_for_allow = yes -- Uncomment
** set_auth_type = no -- Uncommented and changed
=== modules/mschap ===
* Under mschap {}:
** authtype = MS-CHAP -- Addition
** use_mppe = yes -- Uncommented and changed
** require_encryption = yes -- Uncommented
** require_strong = yes -- Uncommented
** with_ntdomain_hack = yes -- Uncommented and changed
* Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel)
=== sites-enabled/default ===
* Under authorize {}:
** #chap -- Commented
** #digest -- Commented
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
** #pap -- Commented
* Under authenticate {}:
** #Auth-Type CHAP {} -- Section commented
** #digest -- Commented
** #unix -- Commented
=== sites-enabled/inner-tunnel ===
* Under server inner-tunnel {}:
** #listen {} -- Commented listen block
* Under authorize {}:
** unix -- Uncommented - Old?
** #suffix -- Commented
** ntdomain -- Uncommented
** ldap -- Uncommented
== Caveats ==
* Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration.
** As such, I highly recommend doing TLS on LDAP, since otherwise you might end up with passwords going over the wire in clear-text.
* I know some of the stuff in LDAP isn't fully clear, or some of the more advanced stuff like VLAN assignment. I'll try to clear these up later, but for right now, this should get you up and going.
== Resources used ==
* Sadly I set the majority of this up a long time ago, but I do seem to have some bookmarks, so I'll throw some of them here. Otherwise, I only used one recently from the FreeRADIUS mailing list.
* http://vuksan.com/linux/dot1x/802-1x-LDAP.html -- Decent guide, also covers setting up OpenLDAP and it's ACLs, and device setup.
* http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius
* [http://wiki.freeradius.org/Home The FreeRADIUS Wiki]
* http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg48720.html -- Email thread bookmarked.
* http://lists.freeradius.org/pipermail/freeradius-users/2012-January/058185.html -- This thread, specially this post to get the Dynamic VLAN assignment working.
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. Sometimes I am in the #freeradius channel, sometimes not, but I am usually connected.
ce0400c3a753a2278a10b4544a076b524c807f21
Setting up Cisco Switches for 802.1x Auth
0
8
37
2012-09-29T02:59:12Z
Bpenglase
1
Initial Submit
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/20
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
dot1x violation-mode protect
dot1x control-direction in
dot1x reauthentication
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
!
</syntaxhighlight>
0bb69e8f7634101677eccc67564c2169df16f247
38
37
2012-09-29T03:22:23Z
Bpenglase
1
/* The Code */ More Changes
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
c78754b7e4d9c84293c889cb499fcc25a7a292d8
39
38
2012-09-29T03:42:54Z
Bpenglase
1
/* The Code */
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
* Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
* Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything.
* Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port.
* Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC.
* Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed).
* Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate.
* Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term.
35eeb0f8807bc2e2574be76b8a04d245d9edb215
40
39
2012-09-29T03:43:41Z
Bpenglase
1
Added Resources and Fin
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
* Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
* Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything.
* Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port.
* Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC.
* Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed).
* Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate.
* Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term.
== Resources Used ==
* [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 Certification Guide]
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750)
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750)
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others.
e62366ba055c69da6406829abeb4be395488e5de
41
40
2012-09-29T03:45:40Z
Bpenglase
1
/* Resources Used */
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
* Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
* Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything.
* Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port.
* Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC.
* Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed).
* Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate.
* Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term.
== Resources Used ==
* [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide]
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750)
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750)
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others.
3ba756223978e1e28b517b783753ab7978caa125
42
41
2012-09-29T03:46:35Z
Bpenglase
1
/* The Code */
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
* Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
* Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything.
* Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port.
* Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC.
* Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed).
* Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate.
* Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term.
== Resources Used ==
* [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide]
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750)
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750)
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others.
ffeaa3251de52e55e6afb8d92864722d1eec45d3
43
42
2012-09-29T03:46:48Z
Bpenglase
1
/* The Code */
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
* Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
* Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything.
* Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port.
* Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC.
* Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed).
* Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate.
* Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term.
== Resources Used ==
* [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide]
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750)
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750)
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others.
45deaed94271ba66cc525abef3e9ff65f81b1b23
45
43
2012-09-29T03:57:32Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below.
== What does this page assume? ==
* You have basic Cisco IOS knowledge
** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server)
** Have configured VLANs and 802.1q trunking
* Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up)
** In my case, with LDAP, your user looks something like this:
[[file:Ldap-radius.png]]
* Have your wired clients setup and able to do EAPoL
== My Testing Environment ==
* Several catalyst switch models
** 2950T-24
** 2950G-48
** 3550-24-PWR
** 3750-48-PS
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain.
* Windows 7
* Mac OS X Mountain Lion
== The Code ==
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
aaa new-model
!
!
aaa authentication dot1x default group radius
aaa authorization network default group radius
!
dot1x system-auth-control
!
!
interface FastEthernet0/1
switchport access vlan 999
switchport mode access
dot1x mac-auth-bypass
dot1x pae authenticator
dot1x port-control auto
!
radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234
</syntaxhighlight>
* Thats pretty much about it.
=== Things to note about the code ===
* Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful.
* Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline.
* Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything.
* Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port.
* Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC.
* Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed).
* Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate.
* Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term.
== Resources Used ==
* [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide]
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750)
* http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750)
== Fin ==
I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others.
1f427f334536690107f4bcdf9ece9dac7123cc8d
File:Ldap-radius.png
6
9
44
2012-09-29T03:54:31Z
Bpenglase
1
User configuration in LDAP that will put the user in VLAN 13 upon successful authentication.
wikitext
text/x-wiki
User configuration in LDAP that will put the user in VLAN 13 upon successful authentication.
395f289516b499f5949438c10b0ad2a74fdf84d2
PXE Booting and Utilities Menu
0
10
47
2012-10-13T02:36:21Z
Bpenglase
1
Initial commit, up to DHCP config
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "netboot/ipxe.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* This if statement breaks the "infinite loop"
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE.
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
54a4af9d2c556a48a917b3a13e5b5e276b173a8a
48
47
2012-10-13T03:27:02Z
Bpenglase
1
Post for the night, up to boot.php, and some commenting.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* This if statement breaks the "infinite loop"
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE.
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deploymeny Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on Freenode\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.com.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
* Woah!<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://10.0.3.2/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
//echo "set 66:ipv4 10.0.3.99\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function gparted() {
echo ":gparted\n";
echo "kernel http://10.0.3.2/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://10.0.3.2/gparted/live/filesystem.squashfs\n";
echo "initrd http://10.0.3.2/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://10.0.3.2/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://10.0.3.2/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://10.0.3.2/memtest.0\n";
}
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
function vesamenu() {
global $plembed;
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://10.0.3.2/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://10.0.3.2/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
//echo "imgargs tboot.b00 kernelopt=runweasel\n";
//echo "imgargs tboot.b00 ks=\${base-url}ks.cfg\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
* More continuing tomorrow...
1d48ce05428567cf3e6efaee5814da1153f6bf03
49
48
2012-10-13T03:30:56Z
Bpenglase
1
/* dhcpd.conf */ Included link for chainloading/ breaking the loop
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deploymeny Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on Freenode\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.com.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
* Woah!<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://10.0.3.2/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
//echo "set 66:ipv4 10.0.3.99\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function gparted() {
echo ":gparted\n";
echo "kernel http://10.0.3.2/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://10.0.3.2/gparted/live/filesystem.squashfs\n";
echo "initrd http://10.0.3.2/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://10.0.3.2/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://10.0.3.2/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://10.0.3.2/memtest.0\n";
}
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
function vesamenu() {
global $plembed;
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://10.0.3.2/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://10.0.3.2/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
//echo "imgargs tboot.b00 kernelopt=runweasel\n";
//echo "imgargs tboot.b00 ks=\${base-url}ks.cfg\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
* More continuing tomorrow...
5fb1fd0a176b5d4142ea4bc40e369025828062fb
File:Ipxemenu1.png
6
11
50
2012-10-13T17:09:39Z
Bpenglase
1
first screen of the iPXE menu
wikitext
text/x-wiki
first screen of the iPXE menu
6532ec5eb0b2079c765349012a9602f4caf9e058
File:Ipxemenu2.png
6
12
51
2012-10-13T17:10:21Z
Bpenglase
1
Second page of the iPXE menu
wikitext
text/x-wiki
Second page of the iPXE menu
e0b24a5334eccdfd902a36f83a368fb45f388895
52
51
2012-10-13T17:12:50Z
Bpenglase
1
Bpenglase uploaded a new version of "[[File:Ipxemenu2.png]]": second page of the iPXE menu, with corrected wording.
wikitext
text/x-wiki
Second page of the iPXE menu
e0b24a5334eccdfd902a36f83a368fb45f388895
53
52
2012-10-13T17:14:14Z
Bpenglase
1
Bpenglase uploaded a new version of "[[File:Ipxemenu2.png]]": Yet another upload, with corrected spelling.
wikitext
text/x-wiki
Second page of the iPXE menu
e0b24a5334eccdfd902a36f83a368fb45f388895
66
53
2012-10-14T19:34:01Z
Bpenglase
1
Bpenglase uploaded a new version of "[[File:Ipxemenu2.png]]": Updated to reflect new windows7 installer.
wikitext
text/x-wiki
Second page of the iPXE menu
e0b24a5334eccdfd902a36f83a368fb45f388895
PXE Booting and Utilities Menu
0
10
54
49
2012-10-13T17:59:54Z
Bpenglase
1
Submit so I don't have to keep reformatting the thing when it screws up! Ugh....
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="89">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
fccac010be3d8c47006ce8b05111d39571abdaf0
55
54
2012-10-13T18:05:46Z
Bpenglase
1
Corrected numbering.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
--
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
bdbb7eb15a7910b1d12290184c5338aaef3df7c6
56
55
2012-10-13T18:15:42Z
Bpenglase
1
Finished comments on boot.php, and added isolinux.cfg for esxi
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
--
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
--
* This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg (esxi) ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
459d0c36fbc55c8df76a12f8a0c0cd9f65b63e62
57
56
2012-10-13T18:42:15Z
Bpenglase
1
Added FIN section, and resources
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
--
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
--
* This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* [http://ipxe.org] -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* [http://lists.ipxe.org/pipermail/ipxe-devel/] -- iPXE Mailing List
* [http://etherboot.org] -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* [http://www.networksorcery.com/enp/protocol/bootp/options.htm] -- General DHCP Options
* [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/] -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* [https://gist.github.com/2234639] -- Robin Smidsrød's iPXE menu
* [http://www.youtube.com/watch?v=GofOqhO6VVM] -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
9f157aa3da6e697be4b53f8a73748bfe5fd0ac80
58
57
2012-10-13T18:44:25Z
Bpenglase
1
removed brackets from the URLs
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
--
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
--
* This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
112305ea078989610537d8aea7643a5467098082
59
58
2012-10-13T18:52:34Z
Bpenglase
1
/* dhcpd.conf */ added link to iPXE DHCP Options
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
--
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
--
* This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
6548fc355f61ddfff41eb5f0039233d250013057
60
59
2012-10-13T18:55:22Z
Bpenglase
1
/* ipxe.kkpxe */ updated filename.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
$mac = "";
$servername = $_SERVER['SERVER_NAME'];
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
}
header ( "Content-type: text/plain" );
</syntaxhighlight>
--
* The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
if ( $mac != "" ) {
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd http://boot.example.com/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
echo "boot";
} else {
exit();
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it makes sure a MAC address is set, otherwise it just exits to an empty file
* Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
--
* This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
85909232319c1268c5e54661fef490f184d73475
61
60
2012-10-14T19:09:33Z
Bpenglase
1
/* boot.php */ Updating, but submitting so the formatting doesn't go off again...
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
echo ":esxi5sl\n";
echo "set 210:string http://boot.example.com/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain http://boot.example.com/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103">
function qwipe() {
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set net0/next-server 10.0.3.99\n";
echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132">
function gparted() {
echo ":gparted\n";
echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n";
echo "initrd http://boot.example.com/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
echo ":dft\n";
echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n";
}
function memtest() {
echo ":memtest\n";
echo "chain http://boot.example.com/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170">
function sanbootpe() {
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
echo ":wimboot\n";
echo "kernel wimboot\n";
echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd winpe/Boot/BCD BCD\n";
echo "initrd winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd winpe/Boot/boot.wim boot.wim\n";
echo "imgstat\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
echo ":vesamenu\n";
echo "set 210:string http://boot.example.com/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
echo ":esxi5\n";
echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n";
echo "echo failing back\n";
echo "goto end\n";
echo "set base-url http://boot.example.com/esxi5/\n";
echo "kernel \${base-url}tboot runweasel\n";
echo "module \${base-url}b.b00\n";
echo "module \${base-url}useropts.gz\n";
echo "module \${base-url}k.b00\n";
echo "module \${base-url}a.b00\n";
echo "module \${base-url}ata-pata.v00\n";
echo "module \${base-url}ata-pata.v01\n";
echo "module \${base-url}ata-pata.v02\n";
echo "module \${base-url}ata-pata.v03\n";
echo "module \${base-url}ata-pata.v04\n";
echo "module \${base-url}ata-pata.v05\n";
echo "module \${base-url}ata-pata.v06\n";
echo "module \${base-url}ata-pata.v07\n";
echo "module \${base-url}block-cc.v00\n";
echo "module \${base-url}ehci-ehc.v00\n";
echo "module \${base-url}s.v00\n";
echo "module \${base-url}weaselin.i00\n";
echo "module \${base-url}ima-qla4.v00\n";
echo "module \${base-url}ipmi-ipm.v00\n";
echo "module \${base-url}ipmi-ipm.v01\n";
echo "module \${base-url}ipmi-ipm.v02\n";
echo "module \${base-url}misc-cni.v00\n";
echo "module \${base-url}misc-dri.v00\n";
echo "module \${base-url}net-be2n.v00\n";
echo "module \${base-url}net-bnx2.v00\n";
echo "module \${base-url}net-bnx2.v01\n";
echo "module \${base-url}net-cnic.v00\n";
echo "module \${base-url}net-e100.v00\n";
echo "module \${base-url}net-e100.v01\n";
echo "module \${base-url}net-enic.v00\n";
echo "module \${base-url}net-forc.v00\n";
echo "module \${base-url}net-igb.v00\n";
echo "module \${base-url}net-ixgb.v00\n";
echo "module \${base-url}net-nx-n.v00\n";
echo "module \${base-url}net-r816.v00\n";
echo "module \${base-url}net-r816.v01\n";
echo "module \${base-url}net-s2io.v00\n";
echo "module \${base-url}net-sky2.v00\n";
echo "module \${base-url}net-tg3.v00\n";
echo "module \${base-url}ohci-usb.v00\n";
echo "module \${base-url}sata-ahc.v00\n";
echo "module \${base-url}sata-ata.v00\n";
echo "module \${base-url}sata-sat.v00\n";
echo "module \${base-url}sata-sat.v01\n";
echo "module \${base-url}sata-sat.v02\n";
echo "module \${base-url}sata-sat.v03\n";
echo "module \${base-url}scsi-aac.v00\n";
echo "module \${base-url}scsi-adp.v00\n";
echo "module \${base-url}scsi-aic.v00\n";
echo "module \${base-url}scsi-bnx.v00\n";
echo "module \${base-url}scsi-fni.v00\n";
echo "module \${base-url}scsi-hps.v00\n";
echo "module \${base-url}scsi-ips.v00\n";
echo "module \${base-url}scsi-lpf.v00\n";
echo "module \${base-url}scsi-meg.v00\n";
echo "module \${base-url}scsi-meg.v01\n";
echo "module \${base-url}scsi-meg.v02\n";
echo "module \${base-url}scsi-mpt.v00\n";
echo "module \${base-url}scsi-mpt.v01\n";
echo "module \${base-url}scsi-mpt.v02\n";
echo "module \${base-url}scsi-qla.v00\n";
echo "module \${base-url}scsi-qla.v01\n";
echo "module \${base-url}scsi-rst.v00\n";
echo "module \${base-url}uhci-usb.v00\n";
echo "module \${base-url}tools.t00\n";
echo "module \${base-url}imgdb.tgz\n";
echo "module \${base-url}imgpayld.tgz\n";
echo "imgstat\n";
echo "boot\n";
}
?>
</syntaxhighlight>
--
* This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
c2f4bd3b1735ee998b02d819352df2794993a54d
62
61
2012-10-14T19:24:17Z
Bpenglase
1
/* boot.php */ Finished updating. Need to update line numbers.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function win7pro64() {
global $servername,$serverproto;
echo ":win7pro64\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/BCD BCD\n";
echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
global $servername,$serverproto;
echo ":esxi5sl\n";
echo "set 210:string $serverproto$servername/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain $serverproto$servername/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131">
function qwipe() {
global $servername,$serverproto;
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
global $servername,$serverproto;
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
global $servername,$serverproto;
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set wdsserver:ipv4 10.0.3.99\n";
echo "set net0/next-server \${wdsserver}\n";
echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164">
function gparted() {
global $servername,$serverproto;
echo ":gparted\n";
echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n";
echo "initrd $serverproto$servername/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
global $servername,$serverproto;
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
global $servername,$serverproto;
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
global $servername,$serverproto;
echo ":dft\n";
echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n";
}
function memtest() {
global $servername,$serverproto;
echo ":memtest\n";
echo "chain $serverproto$servername/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="206">
function sanbootpe() {
global $servername,$serverproto;
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
global $servername,$serverproto;
echo ":wimboot\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185">
function vesamenu() {
global $servername,$serverproto;
echo ":vesamenu\n";
echo "set 210:string $serverproto$servername/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
global $servername,$serverproto;
echo ":esxi5\n";
echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n";
echo "goto end\n";
}
?>
</syntaxhighlight>
--
* Chains to an ipxe config in the esxi51 directory, to load the ESXi installer.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
7a04ed519a1a544b3a9c746cd53f739bec0e57ad
63
62
2012-10-14T19:25:33Z
Bpenglase
1
/* boot.php */ Updated line numbers.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function win7pro64() {
global $servername,$serverproto;
echo ":win7pro64\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/BCD BCD\n";
echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
global $servername,$serverproto;
echo ":esxi5sl\n";
echo "set 210:string $serverproto$servername/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain $serverproto$servername/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131">
function qwipe() {
global $servername,$serverproto;
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
global $servername,$serverproto;
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
global $servername,$serverproto;
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set wdsserver:ipv4 10.0.3.99\n";
echo "set net0/next-server \${wdsserver}\n";
echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164">
function gparted() {
global $servername,$serverproto;
echo ":gparted\n";
echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n";
echo "initrd $serverproto$servername/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
global $servername,$serverproto;
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
global $servername,$serverproto;
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
global $servername,$serverproto;
echo ":dft\n";
echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n";
}
function memtest() {
global $servername,$serverproto;
echo ":memtest\n";
echo "chain $serverproto$servername/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207">
function sanbootpe() {
global $servername,$serverproto;
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
global $servername,$serverproto;
echo ":wimboot\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="221">
function vesamenu() {
global $servername,$serverproto;
echo ":vesamenu\n";
echo "set 210:string $serverproto$servername/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
global $servername,$serverproto;
echo ":esxi5\n";
echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n";
echo "goto end\n";
}
?>
</syntaxhighlight>
--
* Chains to an ipxe config in the esxi51 directory, to load the ESXi installer.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
f681f790818b732aba04b9cc54e3a0da5d6367d4
64
63
2012-10-14T19:26:18Z
Bpenglase
1
/* boot.php */ Updated line numbers.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function win7pro64() {
global $servername,$serverproto;
echo ":win7pro64\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/BCD BCD\n";
echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
global $servername,$serverproto;
echo ":esxi5sl\n";
echo "set 210:string $serverproto$servername/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain $serverproto$servername/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131">
function qwipe() {
global $servername,$serverproto;
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
global $servername,$serverproto;
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
global $servername,$serverproto;
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set wdsserver:ipv4 10.0.3.99\n";
echo "set net0/next-server \${wdsserver}\n";
echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164">
function gparted() {
global $servername,$serverproto;
echo ":gparted\n";
echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n";
echo "initrd $serverproto$servername/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
global $servername,$serverproto;
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
global $servername,$serverproto;
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
global $servername,$serverproto;
echo ":dft\n";
echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n";
}
function memtest() {
global $servername,$serverproto;
echo ":memtest\n";
echo "chain $serverproto$servername/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207">
function sanbootpe() {
global $servername,$serverproto;
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
global $servername,$serverproto;
echo ":wimboot\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223">
function vesamenu() {
global $servername,$serverproto;
echo ":vesamenu\n";
echo "set 210:string $serverproto$servername/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
global $servername,$serverproto;
echo ":esxi5\n";
echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n";
echo "goto end\n";
}
?>
</syntaxhighlight>
--
* Chains to an ipxe config in the esxi51 directory, to load the ESXi installer.
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
6ed362f715f522a6c480360530682f10e1d29f92
65
64
2012-10-14T19:31:29Z
Bpenglase
1
/* Files */ Adds native iPXE loading of esxi5.1
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "undionly.kkpxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.kkpxe ===
* This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function win7pro64() {
global $servername,$serverproto;
echo ":win7pro64\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/BCD BCD\n";
echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
global $servername,$serverproto;
echo ":esxi5sl\n";
echo "set 210:string $serverproto$servername/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain $serverproto$servername/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131">
function qwipe() {
global $servername,$serverproto;
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
global $servername,$serverproto;
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
global $servername,$serverproto;
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set wdsserver:ipv4 10.0.3.99\n";
echo "set net0/next-server \${wdsserver}\n";
echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164">
function gparted() {
global $servername,$serverproto;
echo ":gparted\n";
echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n";
echo "initrd $serverproto$servername/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
global $servername,$serverproto;
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
global $servername,$serverproto;
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
global $servername,$serverproto;
echo ":dft\n";
echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n";
}
function memtest() {
global $servername,$serverproto;
echo ":memtest\n";
echo "chain $serverproto$servername/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207">
function sanbootpe() {
global $servername,$serverproto;
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
global $servername,$serverproto;
echo ":wimboot\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223">
function vesamenu() {
global $servername,$serverproto;
echo ":vesamenu\n";
echo "set 210:string $serverproto$servername/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
global $servername,$serverproto;
echo ":esxi5\n";
echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n";
echo "goto end\n";
}
?>
</syntaxhighlight>
--
* Chains to an ipxe config in the esxi51 directory, to load the ESXi installer.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
=== esxi51.ipxe ===
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
#!ipxe
imgfree
kernel tboot runweasel
module b.b00
module k.b00
module chardevs
module a.b00
module user.b00
module s.v00
module ata_pata.v00
module ata_pata.v01
module ata_pata.v02
module ata_pata.v03
module ata_pata.v04
module ata_pata.v05
module ata_pata.v06
module ata_pata.v07
module block_cc.v00
module ehci_ehc.v00
module weaselin.t00
module esx_dvfi.v00
module xlibs.v00
module ima_qla4.v00
module ipmi_ipm.v00
module ipmi_ipm.v01
module ipmi_ipm.v02
module misc_cni.v00
module misc_dri.v00
module net_be2n.v00
module net_bnx2.v00
module net_bnx2.v01
module net_cnic.v00
module net_e100.v00
module net_e100.v01
module net_enic.v00
module net_forc.v00
module net_igb.v00
module net_ixgb.v00
module net_nx_n.v00
module net_r816.v00
module net_r816.v01
module net_s2io.v00
module net_sky2.v00
module net_tg3.v00
module net_vmxn.v00
module ohci_usb.v00
module sata_ahc.v00
module sata_ata.v00
module sata_sat.v00
module sata_sat.v01
module sata_sat.v02
module sata_sat.v03
module sata_sat.v04
module scsi_aac.v00
module scsi_adp.v00
module scsi_aic.v00
module scsi_bnx.v00
module scsi_fni.v00
module scsi_hps.v00
module scsi_ips.v00
module scsi_lpf.v00
module scsi_meg.v00
module scsi_meg.v01
module scsi_meg.v02
module scsi_mpt.v00
module scsi_mpt.v01
module scsi_mpt.v02
module scsi_qla.v00
module scsi_qla.v01
module scsi_rst.v00
module uhci_usb.v00
module tools.t00
module xorg.v00
module imgdb.tgz
module imgpayld.tgz
boot
</syntaxhighlight>
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
76863403e43005a73ac73b8e7d361df7f399c3dd
67
65
2012-10-14T20:08:55Z
Bpenglase
1
/* Files */ Edited ipxe file that loads.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.pxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.pxe ===
* This file is built from the iPXE source, running "make bin/ipxe.pxe", then copying the bin/ipxe.pxe file to your TFTP server's root directory
* More information on the extensions can be found [http://etherboot.org/wiki/gpxe_imagetypes here on the Etherboot website]
* As stated in the website linked above, pxe unloads the stack, which then means ipxe relies on it's own drivers for the network card. If you to keep the driver loaded, you may want to consider using .kpxe or .kkpxe
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function win7pro64() {
global $servername,$serverproto;
echo ":win7pro64\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/BCD BCD\n";
echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
global $servername,$serverproto;
echo ":esxi5sl\n";
echo "set 210:string $serverproto$servername/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain $serverproto$servername/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131">
function qwipe() {
global $servername,$serverproto;
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
global $servername,$serverproto;
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
global $servername,$serverproto;
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set wdsserver:ipv4 10.0.3.99\n";
echo "set net0/next-server \${wdsserver}\n";
echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164">
function gparted() {
global $servername,$serverproto;
echo ":gparted\n";
echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n";
echo "initrd $serverproto$servername/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
global $servername,$serverproto;
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
global $servername,$serverproto;
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
global $servername,$serverproto;
echo ":dft\n";
echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n";
}
function memtest() {
global $servername,$serverproto;
echo ":memtest\n";
echo "chain $serverproto$servername/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207">
function sanbootpe() {
global $servername,$serverproto;
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
global $servername,$serverproto;
echo ":wimboot\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223">
function vesamenu() {
global $servername,$serverproto;
echo ":vesamenu\n";
echo "set 210:string $serverproto$servername/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
global $servername,$serverproto;
echo ":esxi5\n";
echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n";
echo "goto end\n";
}
?>
</syntaxhighlight>
--
* Chains to an ipxe config in the esxi51 directory, to load the ESXi installer.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
=== esxi51.ipxe ===
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
#!ipxe
imgfree
kernel tboot runweasel
module b.b00
module k.b00
module chardevs
module a.b00
module user.b00
module s.v00
module ata_pata.v00
module ata_pata.v01
module ata_pata.v02
module ata_pata.v03
module ata_pata.v04
module ata_pata.v05
module ata_pata.v06
module ata_pata.v07
module block_cc.v00
module ehci_ehc.v00
module weaselin.t00
module esx_dvfi.v00
module xlibs.v00
module ima_qla4.v00
module ipmi_ipm.v00
module ipmi_ipm.v01
module ipmi_ipm.v02
module misc_cni.v00
module misc_dri.v00
module net_be2n.v00
module net_bnx2.v00
module net_bnx2.v01
module net_cnic.v00
module net_e100.v00
module net_e100.v01
module net_enic.v00
module net_forc.v00
module net_igb.v00
module net_ixgb.v00
module net_nx_n.v00
module net_r816.v00
module net_r816.v01
module net_s2io.v00
module net_sky2.v00
module net_tg3.v00
module net_vmxn.v00
module ohci_usb.v00
module sata_ahc.v00
module sata_ata.v00
module sata_sat.v00
module sata_sat.v01
module sata_sat.v02
module sata_sat.v03
module sata_sat.v04
module scsi_aac.v00
module scsi_adp.v00
module scsi_aic.v00
module scsi_bnx.v00
module scsi_fni.v00
module scsi_hps.v00
module scsi_ips.v00
module scsi_lpf.v00
module scsi_meg.v00
module scsi_meg.v01
module scsi_meg.v02
module scsi_mpt.v00
module scsi_mpt.v01
module scsi_mpt.v02
module scsi_qla.v00
module scsi_qla.v01
module scsi_rst.v00
module uhci_usb.v00
module tools.t00
module xorg.v00
module imgdb.tgz
module imgpayld.tgz
boot
</syntaxhighlight>
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
a749cf4fb6829b98b0f96c1693c54fc529b17f1b
68
67
2012-10-14T20:11:07Z
Bpenglase
1
/* Resources Used */ added forum link
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here.
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of PHP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Linux, Distro: Gentoo (~AMD64 "Unstable")
* Apache 2.4.3
* PHP 5.4.7
* tftp-hpa 5.2
* iPXE (current GIT master)
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== dhcpd.conf ===
* This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions
* Relevant sections of my ISC DHCP config:
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
if exists user-class {
if option user-class = "iPXE" {
filename "http://boot.example.com/preboot.php";
}
} else {
filename "ipxe.pxe";
}
next-server 10.0.3.2;
</syntaxhighlight>
* [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"]
* The filename listed on line 3 is for when iPXE does the DHCP request
* The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE
* The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from
* You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE
=== ipxe.pxe ===
* This file is built from the iPXE source, running "make bin/ipxe.pxe", then copying the bin/ipxe.pxe file to your TFTP server's root directory
* More information on the extensions can be found [http://etherboot.org/wiki/gpxe_imagetypes here on the Etherboot website]
* As stated in the website linked above, pxe unloads the stack, which then means ipxe relies on it's own drivers for the network card. If you to keep the driver loaded, you may want to consider using .kpxe or .kkpxe
=== 01_boot_vhost.conf ===
* This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost
* This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder.
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
<VirtualHost boot.example.com:80>
ServerName boot.example.com
DocumentRoot "/tftp/netboot/"
<Directory "/tftp/netboot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</syntaxhighlight>
=== preboot.php ===
* This is the file that the iPXE client first grabs to see what it needs to do
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
echo "#!ipxe\n";
echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}";
?>
</syntaxhighlight>
* So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL).
=== boot.php ===
* This is the big guy, so I'm going to do some inline comments to explain it
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS">
<?php
// First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct
if (isset($_GET['MAC'])) {
$mac = $_GET['MAC'];
} else {
exit();
}
header ( "Content-type: text/plain" );
// Figure out which protocol we're using
if (isset($_SERVER['HTTPS'])) {
$serverproto = "https://";
} else {
$serverproto = "http://";
}
// If we're running a non-standard port, include it. Otherwise, assume defaults.
if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) {
$servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
} else {
$servername = $_SERVER['SERVER_NAME'];
}
</syntaxhighlight>
--
* The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct
* The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24">
switch ($mac) {
case "00:0c:29:xx:xx:xx":
case "00:e0:b8:xx:xx:xx":
// Testing VM
ipxemenu();
break;
case "bc:ae:c5:xx:xx:xx":
echo "#!ipxe\n";
// Atom - Living Room Frontend
echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n";
// splash=silent,theme:MythTV quiet console=tty1\n";
// echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
case "00:10:18:xx:xx:xx":
echo "#!ipxe\n";
// Athlon 64 HDFE - Bedroom Frontend
echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n";
//splash=silent,theme:MythTV quiet console=tty1\n";
//echo "initrd $serverproto$servername/fe1-initrd.img\n";
break;
default:
ipxemenu();
break;
}
</syntaxhighlight>
--
* This is where the fun begins!
* First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu
* The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP
* Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu)
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48">
function ipxemenu() {
echo "#!ipxe\n";
echo ":menustart\n";
echo "menu iPXE Boot Menu\n";
echo "item --gap -- Diagnostics\n";
echo "item memtest Memtest86+\n";
echo "item dft Drive Fitness Test\n";
echo "item spinrite Spinrite\n";
echo "item hdt Hardware Detection Tool\n";
echo "item b57 b57 Diags\n";
echo "item qwipe Quick Wipe\n";
echo "item --gap -- Internet Boots\n";
echo "item ipxedemo iPXE Demo Boot\n";
echo "item ritboot rit.edu clone of boot.kernel.org\n";
echo "item --gap -- Live Systems\n";
echo "item gparted GParted\n";
echo "item smartos SmartOS\n";
echo "item --gap -- WinPE\n";
echo "item peboot Windows PEBoot via SANBoot\n";
echo "item wimboot Windows PEBoot via WIMBoot\n";
echo "item --gap -- Installers\n";
echo "item esxi5 ESXi 5.1 Installer\n";
echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n";
echo "item freedos FreeDOS 1.1\n";
echo "item vesamenu Vesamenu\n";
echo "item win7pro64 Windows 7 Professional AMD64 Install\n";
echo "item --gap -- Other PXE Systems\n";
echo "item wds Windows Deployment Services\n";
echo "item shell iPXE Shell\n";
echo "item sanhook Sanhook test on FreeNAS\n";
echo "choose os && goto \${os}\n";
echo ":shell\n";
echo "shell\n";
win7pro64();
esxi5sl();
sanhook();
qwipe();
b57();
freedos();
smartos();
gparted();
wds();
hdt();
memtest();
ipxedemo();
ritboot();
dft();
spinrite();
sanbootpe();
wimbootpe();
vesamenu();
esxi5();
echo ":end\n";
}
</syntaxhighlight>
--
* This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu]
* You can check the full syntax from the link above, but it's fairly simple
* This creates the menu that is seen when the client is booted. It looks something like this:
[[file:ipxemenu1.png]]
[[file:ipxemenu2.png]]
* Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine
* I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it)
* Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102">
function win7pro64() {
global $servername,$serverproto;
echo ":win7pro64\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n";
echo "initrd $serverproto$servername/win7instadk/BCD BCD\n";
echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117">
function sanhook() {
echo ":sanhook\n";
echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n";
echo "sleep 5\n";
echo "goto menustart\n";
}
function esxi5sl() {
global $servername,$serverproto;
echo ":esxi5sl\n";
echo "set 210:string $serverproto$servername/esxi5/\n";
echo "set 209:string isolinux.cfg\n";
echo "chain $serverproto$servername/pxelinux.0\n";
echo "goto end\n";
}
</syntaxhighlight>
--
* This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works.
* This will be documented as other files, below.
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131">
function qwipe() {
global $servername,$serverproto;
echo ":qwipe\n";
echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n";
echo "goto menustart\n";
}
function b57() {
global $servername,$serverproto;
echo ":b57\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n";
echo "goto menustart\n";
}
function freedos() {
global $servername,$serverproto;
echo ":freedos\n";
echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n";
echo "goto menustart\n";
}
function smartos() {
echo ":smartos\n";
echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n";
echo "module smartos/platform/i86pc/amd64/boot_archive\n";
echo "boot\n";
echo "sleep 10\n";
}
function wds() {
echo ":wds\n";
echo "set wdsserver:ipv4 10.0.3.99\n";
echo "set net0/next-server \${wdsserver}\n";
echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
</syntaxhighlight>
--
* This one a lot of people may be interested in. This will chain to a Windows Deployment Services.
* Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly.
* Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com
* TODO? Use iPXE arch detection to boot 64bit?
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164">
function gparted() {
global $servername,$serverproto;
echo ":gparted\n";
echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n";
echo "initrd $serverproto$servername/gparted/live/initrd.img\n";
echo "boot\n";
echo "sleep 10\n";
echo "goto menustart\n";
}
function hdt() {
global $servername,$serverproto;
echo ":hdt\n";
echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n";
echo "goto menustart\n";
}
function spinrite() {
global $servername,$serverproto;
echo ":spinrite\n";
echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n";
echo "goto menustart\n";
}
function ipxedemo() {
echo ":ipxedemo\n";
echo "chain http://boot.ipxe.org/demo/boot.php\n";
}
function ritboot() {
echo ":ritboot\n";
echo "set 209:string pxelinux.cfg/default\n";
echo "set 210:string http://boot.rit.edu/bko/\n";
echo "chain http://boot.rit.edu/bko/pxelinux.0\n";
echo "goto :menustart\n";
}
function dft() {
global $servername,$serverproto;
echo ":dft\n";
echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n";
}
function memtest() {
global $servername,$serverproto;
echo ":memtest\n";
echo "chain $serverproto$servername/memtest.0\n";
}
</syntaxhighlight>
--
* This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet).
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207">
function sanbootpe() {
global $servername,$serverproto;
echo ":peboot\n";
echo "set keep-san 1\n";
echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n";
}
function wimbootpe() {
global $servername,$serverproto;
echo ":wimboot\n";
echo "kernel $serverproto$servername/wimboot\n";
echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n";
echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n";
echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n";
echo "boot\n";
}
</syntaxhighlight>
--
* [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory!
--
<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223">
function vesamenu() {
global $servername,$serverproto;
echo ":vesamenu\n";
echo "set 210:string $serverproto$servername/\n";
echo "set 209:string mainmenu.gpxe\n";
echo "chain \${210:string}pxelinux.0\n";
}
function esxi5() {
global $servername,$serverproto;
echo ":esxi5\n";
echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n";
echo "goto end\n";
}
?>
</syntaxhighlight>
--
* Chains to an ipxe config in the esxi51 directory, to load the ESXi installer.
--
=== isolinux.cfg ===
* I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu
* In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
DEFAULT install
LABEL install
KERNEL mboot.c32
APPEND -c boot.cfg
</syntaxhighlight>
=== esxi51.ipxe ===
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
#!ipxe
imgfree
kernel tboot runweasel
module b.b00
module k.b00
module chardevs
module a.b00
module user.b00
module s.v00
module ata_pata.v00
module ata_pata.v01
module ata_pata.v02
module ata_pata.v03
module ata_pata.v04
module ata_pata.v05
module ata_pata.v06
module ata_pata.v07
module block_cc.v00
module ehci_ehc.v00
module weaselin.t00
module esx_dvfi.v00
module xlibs.v00
module ima_qla4.v00
module ipmi_ipm.v00
module ipmi_ipm.v01
module ipmi_ipm.v02
module misc_cni.v00
module misc_dri.v00
module net_be2n.v00
module net_bnx2.v00
module net_bnx2.v01
module net_cnic.v00
module net_e100.v00
module net_e100.v01
module net_enic.v00
module net_forc.v00
module net_igb.v00
module net_ixgb.v00
module net_nx_n.v00
module net_r816.v00
module net_r816.v01
module net_s2io.v00
module net_sky2.v00
module net_tg3.v00
module net_vmxn.v00
module ohci_usb.v00
module sata_ahc.v00
module sata_ata.v00
module sata_sat.v00
module sata_sat.v01
module sata_sat.v02
module sata_sat.v03
module sata_sat.v04
module scsi_aac.v00
module scsi_adp.v00
module scsi_aic.v00
module scsi_bnx.v00
module scsi_fni.v00
module scsi_hps.v00
module scsi_ips.v00
module scsi_lpf.v00
module scsi_meg.v00
module scsi_meg.v01
module scsi_meg.v02
module scsi_mpt.v00
module scsi_mpt.v01
module scsi_mpt.v02
module scsi_qla.v00
module scsi_qla.v01
module scsi_rst.v00
module uhci_usb.v00
module tools.t00
module xorg.v00
module imgdb.tgz
module imgpayld.tgz
boot
</syntaxhighlight>
* The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information.
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://forum.ipxe.org -- iPXE Forums, Great resource for finding answers, or asking questions.
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
3534e0d79e83f65ba8235790a200673fca78aab9
Network & Systems Wrangling
0
6
69
46
2012-10-17T00:11:24Z
Bpenglase
1
Added link for work setup
wikitext
text/x-wiki
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
* [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
* [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
* [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics.
* [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu.
c78c552faa4089b4994b314b05f64de8c93ca4cd
74
69
2013-03-13T23:21:07Z
Bpenglase
1
Added link for Wimboot stuff
wikitext
text/x-wiki
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
* [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
* [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
* [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics.
* [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu.
* [[Installing Windows over a Network]] - Installing Windows 7 Pro over the network, using iPXE, WIMBoot, and Samba.
8bfc4aa0d59391d5af512ff4820df9eced0ec895
IIS and ASP PXE Booting and Vesamenu
0
13
70
2012-10-17T01:57:11Z
Bpenglase
1
Initial submit of the page.
wikitext
text/x-wiki
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]]
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of ASP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Windows Server 2008 R2
* IIS 7
* Classic ASP Scripting
* tftpd32 v4.00 (Service)
* iPXE (current GIT master)
* Syslinux 4.06_Pre11
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== IIS Config ===
<Place holder for the time being>
=== TFTPD32 Config ===
<Place holder for the time being>
=== preboot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim plembed
dim clientip
dim code
dim code1
' Set code
code = "onereallylongcodethatsrandomlygenerated"
' Set Code1
code1 = "secondreallylongcodethatsrandomlygenerated"
' Set IP Subnets that do not get prompted for login
dim nologinips(1)
nologinips(0) = "10.80.18" ' Subnet for NetApps
nologinips(1) = "10.80.38" ' Subnet in Technicians Office
' Get the client's IP Address
clientip = request.servervariables("REMOTE_ADDR")
' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = code then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = code1 then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Compare the current client IP to IPs we shouldn't prompt for login for
for i=0 to ubound(nologinips)
if instr(clientip, nologinips(i)) then
'Perform functions for clients that don't need to be prompted for login
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
end if
next
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf)
response.write("login"&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
%>
</syntaxhighlight>
=== boot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim user
dim pass
dim plembed
dim testing
'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
'this is also used to try and hide the user/pass on the command since it's shown in plain text
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Check to see if user is set, and not empty, if it is, then do the same with the password.
'If set, copy the results to variables
'Otherwise fail over with an error code.
if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then
user = request.querystring("user")
if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then
pass = request.querystring("pass")
else
' If no password is set, fail (either blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1")
response.end
end if
else
' If the username is blank, fail (either left blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1")
response.end
end if
'Verify user/pass combination
'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu
'Otherwise new variables can be added for more functionality)
'First is user 'cs' - Computing Services
if user = "cs" then
' If the password needs to change, change it here
if not pass = "a12345B" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 1
shd = 0
end if
'Next user is 'shd' - Student HelpDesk
elseif user = "shd" then
' If the password needs to change, change it here
if not pass = "B54321a" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 0
shd = 1
end if
else
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Check the MAC, this is where we can specify certain PCs get certain things
' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe
response.write("#!ipxe" & vbCrLF)
Select Case mac
Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with.
ipxemenu
Case "84:2b:2b:xx:xx:xx" ' Dell 980
ipxemenu
Case Else
' Fall back and set the pxelinux variables and what variables should work with what menus
' Variable here (current) set based on username provided
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
End Select
sub ipxemenu()
response.write(":mainmenu" & vbcrlf)
response.write("menu Work Netboot" & vbcrlf)
response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf)
response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf)
response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf)
response.write("item --key m memtest Memtest" & vbcrlf)
response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf)
response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf)
response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf)
response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf)
response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf)
response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf)
response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf)
response.write("item --key p pmagic Parted Magic" & vbcrlf)
response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf)
response.write("item --gap -- ---------- Other Options ----------" & vbcrlf)
response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf)
response.write("item --key i installers Installers Submenu" & vbcrlf)
response.write("item --key x shell iPXE Shell" & vbcrlf)
response.write("item default Default VesaMenu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":dft" & vbcrlf)
response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":wddld" & vbcrlf)
response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":nboot" & vbcrlf)
response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf)
response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf)
response.write("item --key t tstation Thinstation" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":installers" & vbcrlf)
response.write("menu Work Netboot - Installers Menu" & vbcrlf)
response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf)
response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf)
response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf)
response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":memtest" & vbcrlf)
response.write("chain memtest.0" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":esxi51sl" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
response.write("set 209:string esxi51/esxi.cfg" & vbcrlf)
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write("goto end" & vbcrlf)
response.write(":esxi51" & vbcrlf)
response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf)
response.write("goto end" & vbcrlf)
response.write(":wimboot" & vbcrlf)
response.write("imgfree" & vbcrlf)
response.write("kernel wimboot" & vbcrlf)
response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf)
response.write("initrd ghostpe/BCD BCD" & vbcrlf)
response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf)
response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf)
response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf)
response.write("boot" & vbcrlf)
response.write(":7x64" & vbcrlf)
response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf)
response.write(":7x32" & vbcrlf)
response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf)
response.write(":default" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write(":end" & vbcrlf)
end sub
%>
</syntaxhighlight>
4dc00d1287174e982b09f3ef1a1e45939d56c910
71
70
2012-10-17T02:04:53Z
Bpenglase
1
Added under construction
wikitext
text/x-wiki
<center>'''<big>This is under construction and may not be complete</big>''' </center>
== Heading text ==
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]]
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of ASP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Windows Server 2008 R2
* IIS 7
* Classic ASP Scripting
* tftpd32 v4.00 (Service)
* iPXE (current GIT master)
* Syslinux 4.06_Pre11
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== IIS Config ===
<Place holder for the time being>
=== TFTPD32 Config ===
<Place holder for the time being>
=== preboot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim plembed
dim clientip
dim code
dim code1
' Set code
code = "onereallylongcodethatsrandomlygenerated"
' Set Code1
code1 = "secondreallylongcodethatsrandomlygenerated"
' Set IP Subnets that do not get prompted for login
dim nologinips(1)
nologinips(0) = "10.80.18" ' Subnet for NetApps
nologinips(1) = "10.80.38" ' Subnet in Technicians Office
' Get the client's IP Address
clientip = request.servervariables("REMOTE_ADDR")
' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = code then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = code1 then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Compare the current client IP to IPs we shouldn't prompt for login for
for i=0 to ubound(nologinips)
if instr(clientip, nologinips(i)) then
'Perform functions for clients that don't need to be prompted for login
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
end if
next
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf)
response.write("login"&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
%>
</syntaxhighlight>
=== boot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim user
dim pass
dim plembed
dim testing
'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
'this is also used to try and hide the user/pass on the command since it's shown in plain text
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Check to see if user is set, and not empty, if it is, then do the same with the password.
'If set, copy the results to variables
'Otherwise fail over with an error code.
if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then
user = request.querystring("user")
if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then
pass = request.querystring("pass")
else
' If no password is set, fail (either blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1")
response.end
end if
else
' If the username is blank, fail (either left blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1")
response.end
end if
'Verify user/pass combination
'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu
'Otherwise new variables can be added for more functionality)
'First is user 'cs' - Computing Services
if user = "cs" then
' If the password needs to change, change it here
if not pass = "a12345B" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 1
shd = 0
end if
'Next user is 'shd' - Student HelpDesk
elseif user = "shd" then
' If the password needs to change, change it here
if not pass = "B54321a" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 0
shd = 1
end if
else
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Check the MAC, this is where we can specify certain PCs get certain things
' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe
response.write("#!ipxe" & vbCrLF)
Select Case mac
Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with.
ipxemenu
Case "84:2b:2b:xx:xx:xx" ' Dell 980
ipxemenu
Case Else
' Fall back and set the pxelinux variables and what variables should work with what menus
' Variable here (current) set based on username provided
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
End Select
sub ipxemenu()
response.write(":mainmenu" & vbcrlf)
response.write("menu Work Netboot" & vbcrlf)
response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf)
response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf)
response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf)
response.write("item --key m memtest Memtest" & vbcrlf)
response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf)
response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf)
response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf)
response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf)
response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf)
response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf)
response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf)
response.write("item --key p pmagic Parted Magic" & vbcrlf)
response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf)
response.write("item --gap -- ---------- Other Options ----------" & vbcrlf)
response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf)
response.write("item --key i installers Installers Submenu" & vbcrlf)
response.write("item --key x shell iPXE Shell" & vbcrlf)
response.write("item default Default VesaMenu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":dft" & vbcrlf)
response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":wddld" & vbcrlf)
response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":nboot" & vbcrlf)
response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf)
response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf)
response.write("item --key t tstation Thinstation" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":installers" & vbcrlf)
response.write("menu Work Netboot - Installers Menu" & vbcrlf)
response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf)
response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf)
response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf)
response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":memtest" & vbcrlf)
response.write("chain memtest.0" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":esxi51sl" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
response.write("set 209:string esxi51/esxi.cfg" & vbcrlf)
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write("goto end" & vbcrlf)
response.write(":esxi51" & vbcrlf)
response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf)
response.write("goto end" & vbcrlf)
response.write(":wimboot" & vbcrlf)
response.write("imgfree" & vbcrlf)
response.write("kernel wimboot" & vbcrlf)
response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf)
response.write("initrd ghostpe/BCD BCD" & vbcrlf)
response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf)
response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf)
response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf)
response.write("boot" & vbcrlf)
response.write(":7x64" & vbcrlf)
response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf)
response.write(":7x32" & vbcrlf)
response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf)
response.write(":default" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write(":end" & vbcrlf)
end sub
%>
</syntaxhighlight>
6e923137d16a62b0771bd2211fa8e44733d197c3
72
71
2012-10-17T02:18:50Z
Bpenglase
1
Submitted rest of the files. Will comment it all later.
wikitext
text/x-wiki
<center>'''<big>This is under construction and may not be complete</big>''' </center>
== Heading text ==
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]]
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of ASP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Windows Server 2008 R2
* IIS 7
* Classic ASP Scripting
* tftpd32 v4.00 (Service)
* iPXE (current GIT master)
* Syslinux 4.06_Pre11
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== IIS Config ===
<Place holder for the time being>
=== TFTPD32 Config ===
<Place holder for the time being>
=== preboot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim plembed
dim clientip
dim code
dim code1
' Set code
code = "onereallylongcodethatsrandomlygenerated"
' Set Code1
code1 = "secondreallylongcodethatsrandomlygenerated"
' Set IP Subnets that do not get prompted for login
dim nologinips(1)
nologinips(0) = "10.80.18" ' Subnet for NetApps
nologinips(1) = "10.80.38" ' Subnet in Technicians Office
' Get the client's IP Address
clientip = request.servervariables("REMOTE_ADDR")
' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = code then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = code1 then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Compare the current client IP to IPs we shouldn't prompt for login for
for i=0 to ubound(nologinips)
if instr(clientip, nologinips(i)) then
'Perform functions for clients that don't need to be prompted for login
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
end if
next
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf)
response.write("login"&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
%>
</syntaxhighlight>
=== boot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim user
dim pass
dim plembed
dim testing
'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
'this is also used to try and hide the user/pass on the command since it's shown in plain text
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Check to see if user is set, and not empty, if it is, then do the same with the password.
'If set, copy the results to variables
'Otherwise fail over with an error code.
if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then
user = request.querystring("user")
if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then
pass = request.querystring("pass")
else
' If no password is set, fail (either blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1")
response.end
end if
else
' If the username is blank, fail (either left blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1")
response.end
end if
'Verify user/pass combination
'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu
'Otherwise new variables can be added for more functionality)
'First is user 'cs' - Computing Services
if user = "cs" then
' If the password needs to change, change it here
if not pass = "a12345B" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 1
shd = 0
end if
'Next user is 'shd' - Student HelpDesk
elseif user = "shd" then
' If the password needs to change, change it here
if not pass = "B54321a" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 0
shd = 1
end if
else
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Check the MAC, this is where we can specify certain PCs get certain things
' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe
response.write("#!ipxe" & vbCrLF)
Select Case mac
Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with.
ipxemenu
Case "84:2b:2b:xx:xx:xx" ' Dell 980
ipxemenu
Case Else
' Fall back and set the pxelinux variables and what variables should work with what menus
' Variable here (current) set based on username provided
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
End Select
sub ipxemenu()
response.write(":mainmenu" & vbcrlf)
response.write("menu Work Netboot" & vbcrlf)
response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf)
response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf)
response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf)
response.write("item --key m memtest Memtest" & vbcrlf)
response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf)
response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf)
response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf)
response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf)
response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf)
response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf)
response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf)
response.write("item --key p pmagic Parted Magic" & vbcrlf)
response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf)
response.write("item --gap -- ---------- Other Options ----------" & vbcrlf)
response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf)
response.write("item --key i installers Installers Submenu" & vbcrlf)
response.write("item --key x shell iPXE Shell" & vbcrlf)
response.write("item default Default VesaMenu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":dft" & vbcrlf)
response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":wddld" & vbcrlf)
response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":nboot" & vbcrlf)
response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf)
response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf)
response.write("item --key t tstation Thinstation" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":installers" & vbcrlf)
response.write("menu Work Netboot - Installers Menu" & vbcrlf)
response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf)
response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf)
response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf)
response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":memtest" & vbcrlf)
response.write("chain memtest.0" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":esxi51sl" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
response.write("set 209:string esxi51/esxi.cfg" & vbcrlf)
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write("goto end" & vbcrlf)
response.write(":esxi51" & vbcrlf)
response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf)
response.write("goto end" & vbcrlf)
response.write(":wimboot" & vbcrlf)
response.write("imgfree" & vbcrlf)
response.write("kernel wimboot" & vbcrlf)
response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf)
response.write("initrd ghostpe/BCD BCD" & vbcrlf)
response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf)
response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf)
response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf)
response.write("boot" & vbcrlf)
response.write(":7x64" & vbcrlf)
response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf)
response.write(":7x32" & vbcrlf)
response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf)
response.write(":default" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write(":end" & vbcrlf)
end sub
%>
</syntaxhighlight>
=== mainmenu.ipxe ===
<syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS">
ui vesamenu.c32
menu title Network Boot Menu for Work
menu autoboot System will boot to Ghost in # seconds
menu master passwd MasterPassword
menu background backgrounds/pxeboot-800.png
menu resolution 800 600
prompt 0
timeout 1000
menu timeoutrow 99
allowoptions 0
menu rows 25
menu helpmsgrow -1
menu color title 0 #ff00388b #00FFFFFF none
menu color unsel 0 #ffffffff #88000000 std
menu color sel 0 #ff000000 #88c1c1c1 none
menu color hotkey 0 #ff0067ff #80000000 std
menu color hotsel 0 #ff000000 #88c1c1c1 none
menu color disabled 0 #ff0067ff #88000000 std
Label GhostPE
menu label Ghost Tools / PE Environments:
menu disable
label PE
menu indent 2
menu label ^1 Ghost PE Boot Disk (08/06/12)
menu default
kernel memdisk
append iso raw
initrd PEBoot-08_06_12.iso
label Alt-PE
menu indent 4
menu label Ghost PEBoot AltBoot (08/06/12)
COM32 linux.c32
APPEND memdisk initrd=PEBoot-08_06_12.iso iso
Label HardDiag
menu label Hardware Diagnostics:
menu disable
label Memtest
menu indent 2
menu label ^2 Memtest86+ v4.20
kernel memtest86-420
label DFT
menu indent 2
menu label ^3 Drive Fitness Test v4.16
kernel memdisk
append initrd=dft32_v416_b00_install.IMG floppy
label WDDLD
menu indent 2
menu label ^4 WD Data Lifeguard Diagnostic v5.04f
kernel memdisk
append iso raw
initrd Diag504fCD.iso
label SEATOOLS
menu indent 2
menu label ^5 Seagate Seatools for DOS v2.23
kernel memdisk
append iso raw
initrd SeaToolsDOS223ALL.ISO
label HDT
menu indent 2
menu label ^6 Hardware Detection Tool
kernel hdt.c32
label UBCD
menu indent 2
menu label ^7 Ultimate Boot CD v5.1.1
kernel memdisk
append iso raw
initrd ubcd511.iso
label SpinRite
menu indent 2
menu label ^8 SpinRite v6.0
kernel memdisk
append iso raw
initrd spinrite.iso
label DiskWipe
menu label Disk Utilities:
menu disable
label QuickWipe
menu indent 2
menu label ^9 Quick Disk Wipe (Default: Disk 0)
kernel memdisk
append floppy initrd=wipe2.img
label DBAN
menu indent 2
menu label ^0 Darik's Boot And Nuke (DBAN) v2.2.6
kernel memdisk
append iso raw edd=off
initrd dban-2.2.6_i586-fixed.iso
label SalvationHDD
menu indent 2
menu label ^S Salvation HDD Scan & Restore v3.0
kernel memdisk
append floppy initrd=sal-hdd-sr.img
label PartedMagic
menu indent 2
menu label ^P Parted Magic
linux pmagic/bzImage
append initrd=pmagic/initramfs edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw vga=791 loglevel=0 mac_loop=256
label GParted
menu indent 2
menu label ^G GParted (Gnome Partition Editor)
kernel gparted/vmlinuz
append initrd=gparted/initrd.img boot=live config union=aufs noswap noprompt vga=788 fetch=http://netboot.example.com/gparted/filesystem.squashfs noapic edd=off
label OtherNetboot
menu label Other Netboot Systems:
menu disable
label Citrix
menu indent 2
menu label ^C Boot to Citrix Provisioning Service (citrix-dp)
com32 pxechn.c32
append 10.133.2.232::ardbp32.bin
label Thinstation
menu indent 2
menu label ^T Thinstation
kernel thinstation/vmlinuz
append initrd=thinstation/initrd video=uvesafb:1024x768-32,ywrap splash=off console=tty1 loglevel=7 LM=3
label Others
menu label Other Options:
menu disable
label Installers
menu label ^E Installers SubMenu
menu indent 2
kernel vesamenu.c32
append installers.conf
label BIOS
menu disabled
menu label ^B BIOS Updates SubMenu
menu indent 2
kernel vesamenu.c32
append bios/biosupdates.conf
Label Testing
Menu Label ^T Testing SubMenu
menu indent 2
kernel vesamenu.c32
append testing.conf
label MenuExit
menu indent 2
menu label ^Q Exit Menu System - PXELinux Boot Prompt
menu quit
</syntaxhighlight>
=== installers.conf ===
<syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS">
ui vesamenu.c32
menu title Network Installers Menu for Work
menu master passwd MasterPassword
menu background backgrounds/pxeboot-800.png
menu resolution 800 600
prompt 0
menu timeoutrow 99
allowoptions 0
menu rows 22
menu helpmsgrow -1
menu color title 0 #ff00388b #00FFFFFF none
menu color unsel 0 #ffffffff #88000000 std
menu color sel 0 #ff000000 #88c1c1c1 none
menu color hotkey 0 #ff0067ff #80000000 std
menu color hotsel 0 #ff000000 #88c1c1c1 none
menu color disabled 0 #ff0067ff #88000000 std
Label VMWare
menu label VMWare Installers:
menu disable
label ESXi5
menu indent 2
menu label ^1 VMWare ESXi HyperVisor 5.1.0
menu default
kernel esxi51/mboot.c32
append -c /esxi51/boot.cfg
label DebianAMD64
menu label ^2 Debian Squeeze AMD64 Netinstall
menu indent 2
kernel debian-installer/amd64/linux
append vga=788 initrd=debian-installer/amd64/initrd.gz
label DebianAMD64Rescue
menu label ^3 Debian Squeeze AMD64 Rescue mode
menu indent 2
kernel debian-installer/amd64/linux
append vga=788 initrd=debian-installer/amd64/initrd.gz rescue/enable=true
label Debiani386
menu label ^4 Debian Squeeze i386 Netinstall
menu indent 2
kernel debian-installer/i386/linux
append vga=788 initrd=debian-installer/i386/initrd.gz
label Debiani386Rescue
menu label ^5 Debian Squeeze i386 Rescue Mode
menu indent 2
kernel debian-installer/i386/linux
append vga=788 initrd=debian-installer/i386/initrd.gz rescue/enable=true
label MainMenu
menu indent 2
menu label ^Q Return to Main Menu
kernel vesamenu.c32
append mainmenu.ipxe
</syntaxhighlight>
=== mainmenu-shd.ipxe ===
<syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS">
ui vesamenu.c32
menu title Network Boot Menu for Work
menu master passwd MasterPassword
menu background backgrounds/pxeboot-800.png
menu resolution 800 600
prompt 0
timeout 1000
menu timeoutrow 99
allowoptions 0
#menu vshift 0
menu rows 23
menu helpmsgrow -1
menu color title 0 #ff00388b #00FFFFFF none
menu color unsel 0 #ffffffff #88000000 std
menu color sel 0 #ff000000 #88c1c1c1 none
menu color hotkey 0 #ff0067ff #80000000 std
menu color hotsel 0 #ff000000 #88c1c1c1 none
menu color disabled 0 #ff0067ff #88000000 std
Label HardDiag
menu label Hardware Diagnostics:
menu disable
label Memtest
menu indent 2
menu label ^1 Memtest86+ v4.20
kernel memtest86-420
label DFT
menu indent 2
menu label ^2 Drive Fitness Test v4.16
kernel memdisk
append initrd=dft32_v416_b00_install.IMG floppy
label WDDLD
menu indent 2
menu label ^3 WD Data Lifeguard Diagnostic v5.04f
kernel memdisk
append iso raw
initrd Diag504fCD.iso
label SEATOOLS
menu indent 2
menu label ^4 Seagate Seatools for DOS v2.23
kernel memdisk
append iso raw
initrd SeaToolsDOS223ALL.ISO
label HDT
menu indent 2
menu label ^5 Hardware Detection Tool
kernel hdt.c32
label UBCD
menu indent 2
menu label ^6 Ultimate Boot CD v5.1.1
kernel memdisk
append iso raw
initrd ubcd511.iso
label Rescue
menu label System Rescue Utilities
menu disable
label Avira
menu indent 2
menu disable
menu label ^7 Avira AntiVir Rescue System - Currently Broken
kernel memdisk
append iso raw
initrd rescue_system-common-en.iso
label Others
menu label Other Options:
menu disable
label MenuExit
menu indent 2
menu passwd zaxscd
menu label ^Q Exit Menu System - PXELinux Boot Prompt
menu quit
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://forum.ipxe.org -- iPXE Forums, Great resource for finding answers, or asking questions.
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
* http://www.syslinux.org/wiki/index.php/Menu -- Syslinux's Menu documentation
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
5b7956c74e750d63354bed5160dc4768a95f0930
73
72
2012-10-17T02:19:22Z
Bpenglase
1
removed extra header
wikitext
text/x-wiki
<center>'''<big>This is under construction and may not be complete</big>''' </center>
== Intro ==
PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much.
Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me.
So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]]
Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly.
My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin!
== What does this page assume? ==
* You have a working network
* You control your DHCP Server
* You have control of your DNS server
* You have a working webserver
* Basic understanding of ASP
* Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page]
* Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer"
== My Environment ==
* Windows Server 2008 R2
* IIS 7
* Classic ASP Scripting
* tftpd32 v4.00 (Service)
* iPXE (current GIT master)
* Syslinux 4.06_Pre11
* Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc.
== The Basic Process ==
-- My Setup
# Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device
# The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67
# DHCP Server responds with an IP, and the two options
# The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP
# iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67
# The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67.
# iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do.
== Files ==
=== IIS Config ===
<Place holder for the time being>
=== TFTPD32 Config ===
<Place holder for the time being>
=== preboot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim plembed
dim clientip
dim code
dim code1
' Set code
code = "onereallylongcodethatsrandomlygenerated"
' Set Code1
code1 = "secondreallylongcodethatsrandomlygenerated"
' Set IP Subnets that do not get prompted for login
dim nologinips(1)
nologinips(0) = "10.80.18" ' Subnet for NetApps
nologinips(1) = "10.80.38" ' Subnet in Technicians Office
' Get the client's IP Address
clientip = request.servervariables("REMOTE_ADDR")
' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = code then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = code1 then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Compare the current client IP to IPs we shouldn't prompt for login for
for i=0 to ubound(nologinips)
if instr(clientip, nologinips(i)) then
'Perform functions for clients that don't need to be prompted for login
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
end if
next
response.write("#!ipxe"&vbcrlf)
response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf)
response.write("login"&vbcrlf)
response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf)
response.end
%>
</syntaxhighlight>
=== boot.asp ===
<syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS">
<%
response.contenttype="text/plain"
dim mac
dim user
dim pass
dim plembed
dim testing
'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes
'this is also used to try and hide the user/pass on the command since it's shown in plain text
' Check Code0
if not request.querystring("code").count = 0 then
if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then
' Check Code1
if not isEmpty(request.querystring("code1")) then
if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1")
response.end
end if
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
else
' Fail to boot, don't offer login screen again
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1")
response.end
end if
'Check to see if user is set, and not empty, if it is, then do the same with the password.
'If set, copy the results to variables
'Otherwise fail over with an error code.
if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then
user = request.querystring("user")
if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then
pass = request.querystring("pass")
else
' If no password is set, fail (either blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1")
response.end
end if
else
' If the username is blank, fail (either left blank, or login command was not issued)
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1")
response.end
end if
'Verify user/pass combination
'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu
'Otherwise new variables can be added for more functionality)
'First is user 'cs' - Computing Services
if user = "cs" then
' If the password needs to change, change it here
if not pass = "a12345B" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 1
shd = 0
end if
'Next user is 'shd' - Student HelpDesk
elseif user = "shd" then
' If the password needs to change, change it here
if not pass = "B54321a" then
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1")
response.end
else
' Set the proper code for which menu (or other functions) should be returned to the user
cs = 0
shd = 1
end if
else
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1")
response.end
end if
'Get MAC Address into a variable
' This should always be handed over to this script.
If not isEmpty(request.querystring("MAC")) Then
mac = request.querystring("MAC")
else
' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far
response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1")
response.end
End If
' Find out of Pxelinux is embedded or not
If not isEmpty(request.querystring("plembed")) Then
plembed = request.querystring("plembed")
else
plembed = 0
End If
' Check the MAC, this is where we can specify certain PCs get certain things
' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe
response.write("#!ipxe" & vbCrLF)
Select Case mac
Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with.
ipxemenu
Case "84:2b:2b:xx:xx:xx" ' Dell 980
ipxemenu
Case Else
' Fall back and set the pxelinux variables and what variables should work with what menus
' Variable here (current) set based on username provided
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
End Select
sub ipxemenu()
response.write(":mainmenu" & vbcrlf)
response.write("menu Work Netboot" & vbcrlf)
response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf)
response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf)
response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf)
response.write("item --key m memtest Memtest" & vbcrlf)
response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf)
response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf)
response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf)
response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf)
response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf)
response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf)
response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf)
response.write("item --key p pmagic Parted Magic" & vbcrlf)
response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf)
response.write("item --gap -- ---------- Other Options ----------" & vbcrlf)
response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf)
response.write("item --key i installers Installers Submenu" & vbcrlf)
response.write("item --key x shell iPXE Shell" & vbcrlf)
response.write("item default Default VesaMenu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":dft" & vbcrlf)
response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":wddld" & vbcrlf)
response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":nboot" & vbcrlf)
response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf)
response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf)
response.write("item --key t tstation Thinstation" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":installers" & vbcrlf)
response.write("menu Work Netboot - Installers Menu" & vbcrlf)
response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf)
response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf)
response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf)
response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf)
response.write("item --key r mainmenu Return to Main Menu" & vbcrlf)
response.write("choose label && goto ${label}" & vbcrlf)
response.write(":memtest" & vbcrlf)
response.write("chain memtest.0" & vbcrlf)
response.write("goto mainmenu" & vbcrlf)
response.write(":esxi51sl" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
response.write("set 209:string esxi51/esxi.cfg" & vbcrlf)
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write("goto end" & vbcrlf)
response.write(":esxi51" & vbcrlf)
response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf)
response.write("goto end" & vbcrlf)
response.write(":wimboot" & vbcrlf)
response.write("imgfree" & vbcrlf)
response.write("kernel wimboot" & vbcrlf)
response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf)
response.write("initrd ghostpe/BCD BCD" & vbcrlf)
response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf)
response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf)
response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf)
response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf)
response.write("boot" & vbcrlf)
response.write(":7x64" & vbcrlf)
response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf)
response.write(":7x32" & vbcrlf)
response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf)
response.write(":default" & vbcrlf)
response.write("set 210:string http://netboot.example.com/" & vbcrlf)
If cs = 1 Then
response.write("set 209:string mainmenu.ipxe" & vbcrlf)
ElseIf shd = 1 Then
response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf)
End If
If plembed = 1 Then
response.write("imgload pxelinux.0" & vbcrlf)
response.write("imgexec pxelinux.0" & vbcrlf)
Else
response.write("chain ${210:string}pxelinux.0" & vbcrlf)
End If
response.write(":end" & vbcrlf)
end sub
%>
</syntaxhighlight>
=== mainmenu.ipxe ===
<syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS">
ui vesamenu.c32
menu title Network Boot Menu for Work
menu autoboot System will boot to Ghost in # seconds
menu master passwd MasterPassword
menu background backgrounds/pxeboot-800.png
menu resolution 800 600
prompt 0
timeout 1000
menu timeoutrow 99
allowoptions 0
menu rows 25
menu helpmsgrow -1
menu color title 0 #ff00388b #00FFFFFF none
menu color unsel 0 #ffffffff #88000000 std
menu color sel 0 #ff000000 #88c1c1c1 none
menu color hotkey 0 #ff0067ff #80000000 std
menu color hotsel 0 #ff000000 #88c1c1c1 none
menu color disabled 0 #ff0067ff #88000000 std
Label GhostPE
menu label Ghost Tools / PE Environments:
menu disable
label PE
menu indent 2
menu label ^1 Ghost PE Boot Disk (08/06/12)
menu default
kernel memdisk
append iso raw
initrd PEBoot-08_06_12.iso
label Alt-PE
menu indent 4
menu label Ghost PEBoot AltBoot (08/06/12)
COM32 linux.c32
APPEND memdisk initrd=PEBoot-08_06_12.iso iso
Label HardDiag
menu label Hardware Diagnostics:
menu disable
label Memtest
menu indent 2
menu label ^2 Memtest86+ v4.20
kernel memtest86-420
label DFT
menu indent 2
menu label ^3 Drive Fitness Test v4.16
kernel memdisk
append initrd=dft32_v416_b00_install.IMG floppy
label WDDLD
menu indent 2
menu label ^4 WD Data Lifeguard Diagnostic v5.04f
kernel memdisk
append iso raw
initrd Diag504fCD.iso
label SEATOOLS
menu indent 2
menu label ^5 Seagate Seatools for DOS v2.23
kernel memdisk
append iso raw
initrd SeaToolsDOS223ALL.ISO
label HDT
menu indent 2
menu label ^6 Hardware Detection Tool
kernel hdt.c32
label UBCD
menu indent 2
menu label ^7 Ultimate Boot CD v5.1.1
kernel memdisk
append iso raw
initrd ubcd511.iso
label SpinRite
menu indent 2
menu label ^8 SpinRite v6.0
kernel memdisk
append iso raw
initrd spinrite.iso
label DiskWipe
menu label Disk Utilities:
menu disable
label QuickWipe
menu indent 2
menu label ^9 Quick Disk Wipe (Default: Disk 0)
kernel memdisk
append floppy initrd=wipe2.img
label DBAN
menu indent 2
menu label ^0 Darik's Boot And Nuke (DBAN) v2.2.6
kernel memdisk
append iso raw edd=off
initrd dban-2.2.6_i586-fixed.iso
label SalvationHDD
menu indent 2
menu label ^S Salvation HDD Scan & Restore v3.0
kernel memdisk
append floppy initrd=sal-hdd-sr.img
label PartedMagic
menu indent 2
menu label ^P Parted Magic
linux pmagic/bzImage
append initrd=pmagic/initramfs edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw vga=791 loglevel=0 mac_loop=256
label GParted
menu indent 2
menu label ^G GParted (Gnome Partition Editor)
kernel gparted/vmlinuz
append initrd=gparted/initrd.img boot=live config union=aufs noswap noprompt vga=788 fetch=http://netboot.example.com/gparted/filesystem.squashfs noapic edd=off
label OtherNetboot
menu label Other Netboot Systems:
menu disable
label Citrix
menu indent 2
menu label ^C Boot to Citrix Provisioning Service (citrix-dp)
com32 pxechn.c32
append 10.133.2.232::ardbp32.bin
label Thinstation
menu indent 2
menu label ^T Thinstation
kernel thinstation/vmlinuz
append initrd=thinstation/initrd video=uvesafb:1024x768-32,ywrap splash=off console=tty1 loglevel=7 LM=3
label Others
menu label Other Options:
menu disable
label Installers
menu label ^E Installers SubMenu
menu indent 2
kernel vesamenu.c32
append installers.conf
label BIOS
menu disabled
menu label ^B BIOS Updates SubMenu
menu indent 2
kernel vesamenu.c32
append bios/biosupdates.conf
Label Testing
Menu Label ^T Testing SubMenu
menu indent 2
kernel vesamenu.c32
append testing.conf
label MenuExit
menu indent 2
menu label ^Q Exit Menu System - PXELinux Boot Prompt
menu quit
</syntaxhighlight>
=== installers.conf ===
<syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS">
ui vesamenu.c32
menu title Network Installers Menu for Work
menu master passwd MasterPassword
menu background backgrounds/pxeboot-800.png
menu resolution 800 600
prompt 0
menu timeoutrow 99
allowoptions 0
menu rows 22
menu helpmsgrow -1
menu color title 0 #ff00388b #00FFFFFF none
menu color unsel 0 #ffffffff #88000000 std
menu color sel 0 #ff000000 #88c1c1c1 none
menu color hotkey 0 #ff0067ff #80000000 std
menu color hotsel 0 #ff000000 #88c1c1c1 none
menu color disabled 0 #ff0067ff #88000000 std
Label VMWare
menu label VMWare Installers:
menu disable
label ESXi5
menu indent 2
menu label ^1 VMWare ESXi HyperVisor 5.1.0
menu default
kernel esxi51/mboot.c32
append -c /esxi51/boot.cfg
label DebianAMD64
menu label ^2 Debian Squeeze AMD64 Netinstall
menu indent 2
kernel debian-installer/amd64/linux
append vga=788 initrd=debian-installer/amd64/initrd.gz
label DebianAMD64Rescue
menu label ^3 Debian Squeeze AMD64 Rescue mode
menu indent 2
kernel debian-installer/amd64/linux
append vga=788 initrd=debian-installer/amd64/initrd.gz rescue/enable=true
label Debiani386
menu label ^4 Debian Squeeze i386 Netinstall
menu indent 2
kernel debian-installer/i386/linux
append vga=788 initrd=debian-installer/i386/initrd.gz
label Debiani386Rescue
menu label ^5 Debian Squeeze i386 Rescue Mode
menu indent 2
kernel debian-installer/i386/linux
append vga=788 initrd=debian-installer/i386/initrd.gz rescue/enable=true
label MainMenu
menu indent 2
menu label ^Q Return to Main Menu
kernel vesamenu.c32
append mainmenu.ipxe
</syntaxhighlight>
=== mainmenu-shd.ipxe ===
<syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS">
ui vesamenu.c32
menu title Network Boot Menu for Work
menu master passwd MasterPassword
menu background backgrounds/pxeboot-800.png
menu resolution 800 600
prompt 0
timeout 1000
menu timeoutrow 99
allowoptions 0
#menu vshift 0
menu rows 23
menu helpmsgrow -1
menu color title 0 #ff00388b #00FFFFFF none
menu color unsel 0 #ffffffff #88000000 std
menu color sel 0 #ff000000 #88c1c1c1 none
menu color hotkey 0 #ff0067ff #80000000 std
menu color hotsel 0 #ff000000 #88c1c1c1 none
menu color disabled 0 #ff0067ff #88000000 std
Label HardDiag
menu label Hardware Diagnostics:
menu disable
label Memtest
menu indent 2
menu label ^1 Memtest86+ v4.20
kernel memtest86-420
label DFT
menu indent 2
menu label ^2 Drive Fitness Test v4.16
kernel memdisk
append initrd=dft32_v416_b00_install.IMG floppy
label WDDLD
menu indent 2
menu label ^3 WD Data Lifeguard Diagnostic v5.04f
kernel memdisk
append iso raw
initrd Diag504fCD.iso
label SEATOOLS
menu indent 2
menu label ^4 Seagate Seatools for DOS v2.23
kernel memdisk
append iso raw
initrd SeaToolsDOS223ALL.ISO
label HDT
menu indent 2
menu label ^5 Hardware Detection Tool
kernel hdt.c32
label UBCD
menu indent 2
menu label ^6 Ultimate Boot CD v5.1.1
kernel memdisk
append iso raw
initrd ubcd511.iso
label Rescue
menu label System Rescue Utilities
menu disable
label Avira
menu indent 2
menu disable
menu label ^7 Avira AntiVir Rescue System - Currently Broken
kernel memdisk
append iso raw
initrd rescue_system-common-en.iso
label Others
menu label Other Options:
menu disable
label MenuExit
menu indent 2
menu passwd zaxscd
menu label ^Q Exit Menu System - PXELinux Boot Prompt
menu quit
</syntaxhighlight>
== Resources Used ==
* http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too)
* http://forum.ipxe.org -- iPXE Forums, Great resource for finding answers, or asking questions.
* http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List
* http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE.
* http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options
* http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE.
* I'm sure there have been many over the years. As I come up with more, I will add them.
* https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu
* http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation!
* http://www.syslinux.org/wiki/index.php/Menu -- Syslinux's Menu documentation
== Fin ==
These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here.
iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff!
I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server.
One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world.
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
d0841f999f701991d6ed3681659fd3f5bf70c90d
Installing Windows over a Network
0
14
75
2013-03-13T23:41:13Z
Bpenglase
1
New Page! Laying out the format.
wikitext
text/x-wiki
<big>== Under Construction! ==</big>
== Intro ==
Intro Text
== What does this page assume? ==
Assumptions
== My Environment ==
Environment
== The Basic Process ==
Da Basics
== Files ==
Files
== Resources Used ==
Resources
== Fin ==
Final words
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
02133c8ef5f2818bf1b8c16bc48641d33f552e7c
76
75
2013-03-13T23:43:33Z
Bpenglase
1
wikitext
text/x-wiki
<Center> <big><big>Under Construction!!!</big></big> </center>
== Intro ==
Intro Text
== What does this page assume? ==
Assumptions
== My Environment ==
Environment
== The Basic Process ==
Da Basics
== Files ==
Files
== Resources Used ==
Resources
== Fin ==
Final words
For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit!
Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do.
ffc586b58dfd37336604d9ab0da9e10861283034
Getting *nix to Netboot Macs
0
5
77
17
2013-12-13T17:02:12Z
Bpenglase
1
/* Fin */
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
== Fin ==
* <strike>Once OSXDeployment.com is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.</strike> This site has been rolled into AFP548.
* I have learned more about BSDP then I ever wanted to know :)
* I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox.
4788d98f99ca355e40699579b6fdaf3fd54b9dc7
78
77
2013-12-13T17:06:13Z
Bpenglase
1
/* Resources Used to Complete this */ Updated dead URL
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/2006/12/20/howto-configure-gnulinux-to-provide-bsdp-netboot-services/ article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
== Fin ==
* <strike>Once OSXDeployment.com is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.</strike> This site has been rolled into AFP548.
* I have learned more about BSDP then I ever wanted to know :)
* I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox.
dde3de76b456177d2faa59636e2faccbc9a2181f
79
78
2013-12-13T17:19:24Z
Bpenglase
1
/* Caveats */
wikitext
text/x-wiki
== Intro ==
So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work.
== What is this all about? ==
For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation.
The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu.
== What does this page assume? ==
* You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP].
* You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter).
== My Testing Environment ==
* Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0
* (work issued) Apple MacBookPro6,2, Purchased Fall 2010
== The Code ==
* This presents two images to the Alt/Option Boot menu:
** ID: 137, Name: DOE-Image (Also our default image)
** ID: 138, Name: DSR-NB01012012-05122012
* Sets ID 137 to be the Default Image for only holding down N at boot
* Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly)
<syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS">
class "Apple-Intel-Netboot" {
# Limit this class to only Intel Apple machines
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it)
# From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml
# 1 - Subnet Mask
# 3 - Router
# 17 - Root Path
# 43 - Vendor Specific
# 60 - Class ID
if (option dhcp-message-type = 8) {
# on DHCPInform Messages, Us/Our (Server), Them (Client)
option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information
if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) {
log(info, "BSDP_LIST");
# BSDP List
# Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list
option vendor-encapsulated-options
01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:)
03:04: # BSDP option code 3 (length 04) -- Server Identifier
0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex
04:02: # BSDP option code 4 (length 02) -- Server Priority
80:00: # Priority (32768) Dec->Hex
07:04: # BSDP option code 7 (length 04) -- Default Image ID
81:00:00:89: # Image ID - (137) Dec->Hex
# This is what is picked as Default when you only hold down N on the client
#
# 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set,
# Most, including DeployStudio default to NetInstall set.
# Then 0 for Mac OS 9, 1 for Mac OS X (Client)
# 2 for OS X Server, and 3 for Hardware Diagnostics
# 4- through 127 (x4:00-xf:ff) reversed for future use
# And the last two are for the Image ID (Dec->Hex)
# IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range)
# IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID
# and the client will only see one image, and pick a random(?) server to talk to.
#
09: # BSDP option code 9 -- Boot image list
2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A
# This only appears once in the pacakge, no matter how many images you have below
81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID
09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex
81:00:00:8A: # Image ID -- 138
17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name
# Name: DSR-NB01012012-05122012
} elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) {
log(info, "BSDP_SELECT");
# BSDP Select, This is the client selecting which image they want to boot from
# Here we basically do if statements to catch what image is referenced
# Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04)
if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this
log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to
if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89
log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing
# Insert stuff needed to boot here
filename "/osx/i386/booter";
next-server 10.25.64.32;
option root-path = "http://10.25.64.32/build.sparseimage";
} elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A
log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012");
# Insert stuff here needed for boot
# This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server
filename "macnbi-i386/booter";
#Replace 192.168.1.1 with the server's actual IP address.
#Need clarification if NetRestore works for both Intel and PowerPC
#For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server
#option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage";
#option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage";
option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg";
next-server 192.168.1.1;
} else {
log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)");
} # End Image Selection Response
} else {
log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time
} # End Server Check
} # End BSDP Options Check
} # End DHCPInform Messages
} # End Class
</syntaxhighlight>
== Caveats ==
* This does not present the netboot sets to the Startup Disk System Preferences Pane
** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate.
* Would be enabled on all subnets handled by this DHCP server
* Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working
* All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...)
* While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next.
* Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default.
** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily.
** I say 'fail', as it doesn't fail, but the server only knows to hand over the default.
* This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to
**(Think booting a SIU Image, like one created by JAMF [https://jamfnation.jamfsoftware.com/article.html?id=64 Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots.
== Resources Used to Complete this ==
* I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it.
* Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths)
* Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names)
* I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/2006/12/20/howto-configure-gnulinux-to-provide-bsdp-netboot-services/ article on AFP548]
* Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot
* Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List]
* Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times
== Fin ==
* <strike>Once OSXDeployment.com is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.</strike> This site has been rolled into AFP548.
* I have learned more about BSDP then I ever wanted to know :)
* I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox.
59efef303e514af5d19fc6eb6d57cf229946d1ae
The World According to Apple
0
4
80
8
2014-05-31T01:34:47Z
Bpenglase
1
wikitext
text/x-wiki
* [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images.
* [[1]] - [[mw:Special:ExtensionDistributor/SyntaxHighlight_GeSHi]]
3fef09759062435b98efd989869864448ac1ac41
81
80
2014-05-31T01:37:48Z
Bpenglase
1
wikitext
text/x-wiki
* [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images.
386c8f5bd83f11c9535f79e31b35a02ffb997d18
Dabbling in Electronics
0
15
82
2014-06-08T00:44:25Z
Bpenglase
1
Initial Page Creation
wikitext
text/x-wiki
* [[ Raspberry Pi Projects ]] - Place for any of the projects I do using the Raspberry Pi
* [[ BeagleBone Black Projects ]] - Place for any of the projects I do using the BeagleBone Black
* [[ NavSpark Projects ]] - Place for any of the projects I do using the NavSpark/SkyTraq
* [[ ATMega/Arduino Projects ]] - Place for any of the projects I do using an ATMega (or Arduino)
8c08af1674421128cc46c3215679a00d4747b0a5
NavSpark Projects
0
16
83
2014-06-08T01:02:28Z
Bpenglase
1
Created page with "== NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark ] was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gn..."
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark ] was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
cb7399581a0f20c459ae39f5c9086f0655bdaff8
84
83
2014-06-08T01:02:52Z
Bpenglase
1
/* NavSpark */
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark] was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
3f673269fffd9b07c1338e249922004fbbcbfe88
85
84
2014-06-08T01:05:30Z
Bpenglase
1
Initial Page
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
I was luck and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices.
I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location.
Below I'll link in as I create projects that use this chip.
dcbff140f4bd9bf02a40e4a8f2b275a8c0a7450a
86
85
2014-06-08T01:06:11Z
Bpenglase
1
/* NavSpark */
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
I was luck and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices.
I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location.
Below I'll link in as I create projects that use this chip.
4adbd4a2636aad398880c1ad11b83cef868d3294
87
86
2014-06-08T01:06:44Z
Bpenglase
1
/* NavSpark */
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
I was lucky and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices.
I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location.
Below I'll link in as I create projects that use this chip.
848e56000e926377e797bb0cb7c20bedf91cdfa5
88
87
2014-06-08T01:11:48Z
Bpenglase
1
/* NavSpark */
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
I was lucky and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices.
I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location.
Below I'll link in as I create projects that use this chip.
== Projects ==
* [[NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi]] - Using one of the NavSpark modules, specifically the GPS+GLONASS one, use this with the NEMA Data and PPS to setup a Strat 1 NTP Time Source with the Raspberry Pi.
38833dc23c0fb88ac50ea22c68ee8dea5a338da7
97
88
2014-07-05T18:19:28Z
Bpenglase
1
added BBB link
wikitext
text/x-wiki
== NavSpark ==
If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver".
I was lucky and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices.
I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location.
Below I'll link in as I create projects that use this chip.
== Projects ==
* [[NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi]] - Using one of the NavSpark modules, specifically the GPS+GLONASS one, use this with the NEMA Data and PPS to setup a Strat 1 NTP Time Source with the Raspberry Pi. Also now includes an RTC for keeping time between power cycles.
* [[NavSpark GPS+GLONASS Stratum-1 NTP Time Source+RTC with a BeagleBone Black]] - Using one of the NavSpark modules, specifically the GPS+GLONASS one, use this with the NEMA Data and PPS to setup a Strat 1 NTP Time Source with the Raspberry Pi. Also includes an RTC for keeping time between power cycles.
4bf85bebfdc9a8aa99b92f84036bfabb91030ae1
NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi
0
17
89
2014-06-08T01:22:24Z
Bpenglase
1
Initial+Sections
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
e081d5d154e066930d5839290a7435978cd3b427
90
89
2014-06-08T02:09:52Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
9abdd67490fd5bf59265737301162082de154905
91
90
2014-06-08T02:33:50Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
e4b1f5ce4d90bcf4b2334a1ba92954055aa214ef
92
91
2014-06-08T02:48:04Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
251bc7be4dd3d8b026a63a5141647a7093e49097
93
92
2014-06-08T15:36:37Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
cb9220e9967040c27ba8c815406d3d739a016cb0
94
93
2014-06-08T15:48:30Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
595bdb2cd613aeb749217213400040f30565db34
95
94
2014-06-08T15:48:56Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
176a93b1e36f1c45dca6ad655207fd22b9fd72ef
96
95
2014-06-09T01:52:44Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
Uninstall existing ntp, compile/install latest ntp
683fc8427e89aba9e42eabb950247ea5bdee377f
99
96
2014-08-17T03:56:43Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
Custom PCB uses GPIO23
Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger?
apt-get install pps-tools
apt-get install snmp
apt-get install libcap-dev
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
#https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
c4a3db182d15b595628fbbf420d721f42ea90f19
100
99
2014-08-17T06:01:52Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
Update Pi
apt-get update
apt-get distupgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
Custom PCB uses GPIO23
Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger?
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
##rm K05hwclock.sh
ln -s ../init.d/hwclock.sh S10hwclock.sh
update-rc.d hwclock.sh enable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
1df07f62a14428840c4e6c6f3c891a407aa80bc8
NavSpark GPS+GLONASS Stratum-1 NTP Time Source+RTC with a BeagleBone Black
0
18
98
2014-07-05T18:20:16Z
Bpenglase
1
Initial Layout
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
4c3d44f4c7d8345f70e72ce09b6aaeb4a7c831e8
NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi
0
17
101
100
2014-08-18T03:05:27Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
Custom PCB uses GPIO23
Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger?
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
e5907f234bc89fadb621eec9539374c0571ce7ec
102
101
2014-10-13T02:18:32Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0)
edit /etc/inittab, remove serial console
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git
Patch Kernel: http://ntpi.openchaos.org/pps_pi/
Custom PCB uses GPIO23
Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger?
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
eb7eded28692f9119a2b153fb31bb56ff5381222
103
102
2014-10-17T02:49:01Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
52edbf41c077bdf489c1df60eb68f8fdc5f1e8e4
104
103
2014-10-18T02:37:07Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
== What is this all about? ==
== What does this page assume? ==
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
2d67a04da620fad7687dcce6e3e8772f0c713a73
105
104
2014-10-21T03:08:20Z
Bpenglase
1
Starting layout for final page.
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
0e0d7cb9d587d20bdcd79b5f5e5b049bdcfaa2f0
106
105
2014-10-22T01:40:11Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
e0fdcea4d3a72243f41699313f70cf36596b2280
108
106
2014-10-22T01:42:58Z
Bpenglase
1
added picture
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
9071a47e280534bd6c2c54846a630b4071086d22
109
108
2014-10-22T01:43:45Z
Bpenglase
1
adjusted text/picture
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
e155b93051e714a23eee1302a78d7502e981920a
110
109
2014-10-22T01:44:20Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
7603d862a5d9030dceade78cbbfbeba0aab3b1fa
111
110
2014-10-22T01:44:45Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
9dd0e3b400356cfd6453d13bbf35654d19d1e15a
112
111
2014-10-22T01:47:22Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
de259705a78fd8df91fe702eccc61115bc9f72b9
113
112
2014-10-22T01:48:06Z
Bpenglase
1
/* What does this page assume? */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
6626d3bfd36345837e51e8d911032e52f3554c19
114
113
2014-11-03T01:46:19Z
Bpenglase
1
/* What does this page assume? */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Optional====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
9636abaf7c76472e3cc78c6202f600a640313585
115
114
2014-11-04T03:14:16Z
Bpenglase
1
/* What does this page assume? */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set userpassword
set hostname - NTP1
Change GPU memory to 16M (not used for NTP, more memory available to the system)
Enable Kernel i2c
Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get distupgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
17727171e8ab8cc6608dc7af50ef597314bbdaf4
116
115
2015-02-15T07:04:33Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)
General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral
-> Deselect "Old Idle Dynticks Config"
Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"
Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable?
Edit arch/arm/mach-bcm2708/bcm2708.c
line 282 - change gpio to pin 23
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
edit /boot/config.txt
add:
kernel=Image-3187
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ
modprobe i2c-bcm2708
modprobe i2cdev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
200d21dcc6f88ade19551a50cf0ae736cca1f204
117
116
2015-02-15T07:26:22Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)
General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral
-> Deselect "Old Idle Dynticks Config"
Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"
Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable?
Edit arch/arm/mach-bcm2708/bcm2708.c
line 282 - change gpio to pin 23
Custom PCB uses GPIO23
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
edit /boot/config.txt
add:
kernel=Image-3187
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
983f8557d7c07bd5d7e87d95cdad33364bee5a93
118
117
2015-02-18T02:10:09Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)
General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral
-> Deselect "Old Idle Dynticks Config"
Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"
Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
edit /boot/config.txt
add:
kernel=Image-3187
dtoverlay=pps-gpio,gpiopin=<x>
Custom PCB uses GPIO23
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
6beea71ec7e7e31b054ed1385d0414306d1a0ee9
119
118
2015-02-19T23:40:57Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
reboot
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=<x>
Custom PCB uses GPIO23
======================================================================
OLD/INVALID
edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above)
edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above)
KERNEL TIME
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
(Required!)General -> Default Hostname (NTP1)
General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral
-> Deselect "Old Idle Dynticks Config"
Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"
Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
tar -cjf modules.tar.bz2 modtmp/
scp modules.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
edit /boot/config.txt
add:
kernel=Image-3187
=============================================================================================
Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make
now wait ~20minutes
rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address
netmask
gateway
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
6f0e208aa96847de3c868a756d448e6b32b135d6
120
119
2015-02-20T03:09:48Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
9248c7356b4e285e27397489b6d2c1fe7b4e911c
121
120
2015-02-20T03:14:33Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it)
* You know how to wire/breadboard stuff to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations)
* Setting up a cross-compile environment
* Comfortable compiling and installing software/kernel
* Comfortable applying patches
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
8ff21b79ecacaee795ea8529e381c26badc66679
122
121
2015-02-22T23:05:10Z
Bpenglase
1
/* What does this page assume? */ Updated details about Pi models, and cleared up some phrasing, as well as re-worded some items due to differences in how the new kernel allows us to work with things.
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
af7758d30b0e83ccc9930a9cbd6be37f0b1eff20
123
122
2015-02-22T23:11:08Z
Bpenglase
1
/* My Testing Environment */ Added Antenna link
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
d59e49da237c3ecca35a8498f16f8e46003990ca
124
123
2015-02-22T23:17:53Z
Bpenglase
1
/* The Code */ Added intro
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
6d59697522db726ca21744c3212e93f4d3a816ad
125
124
2015-02-22T23:49:38Z
Bpenglase
1
Added section
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup> RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
3399bfcbf1b3214bd30fd0a3db892f55c8e49a09
126
125
2015-02-22T23:50:06Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup> RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
506e41d552213bf79fae5e1547a71d1250bfcb7e
127
126
2015-02-22T23:50:33Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup> RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
c67d918bef33687628763e961de2cd21a48bdfab
128
127
2015-02-22T23:50:54Z
Bpenglase
1
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup> RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
506e41d552213bf79fae5e1547a71d1250bfcb7e
129
128
2015-02-22T23:51:20Z
Bpenglase
1
/* Physical Connections */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
e727ab44a8ac461b7816e303139e03c29cb5ac6d
130
129
2015-02-22T23:51:53Z
Bpenglase
1
/* Physical Connections */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
680697d07fac15fbd3bd2a8ee3783b2f3d279668
131
130
2015-02-23T00:01:43Z
Bpenglase
1
/* Physical Connections */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
ca46a0c0b74dd8e7288fbfcd7429faaa1d33c726
132
131
2015-02-23T00:22:51Z
Bpenglase
1
/* The Code */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
ce48ba4694141b4887f5a11815381385994a7630
133
132
2015-02-23T00:37:46Z
Bpenglase
1
/* The Code */ Added details...
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
17e852a9777e67217504d2b0c3502066d322d887
134
133
2015-02-23T00:40:22Z
Bpenglase
1
/* The Code */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
bbe9fd128c09eb5b1c201863b9e4a4404749559e
135
134
2015-02-23T01:18:24Z
Bpenglase
1
/* The Code */ Code for cross-compile and kernel compiling.
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
d0ff4f2efbd48dad01369c14ad6e3103cbe035df
136
135
2015-02-23T02:31:57Z
Bpenglase
1
/* The Code */ Finished entering steps!
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi:
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download mkknlimg<ref name"mkknlimg">[https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg]</ref>
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download knlinfo <ref name"knlinfo">[https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo]</ref> and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPs & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
f581efa467e861c86f5d84d52d0222ca336b7554
137
136
2015-02-23T02:33:18Z
Bpenglase
1
/* Building the kernel */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download mkknlimg<ref name"mkknlimg">[https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg]</ref>
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download knlinfo <ref name"knlinfo">[https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo]</ref> and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPs & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
70f8d096001c7e01eebd5b066f10eda7c0ea344e
138
137
2015-02-23T02:34:53Z
Bpenglase
1
/* GPs & UDev Rules */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download mkknlimg<ref name"mkknlimg">[https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg]</ref>
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download knlinfo <ref name"knlinfo">[https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo]</ref> and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
67641ec8890fc86e12fc8be8c7c6aec0531949bf
139
138
2015-02-23T02:42:19Z
Bpenglase
1
/* Kernel Time */ Formatting issues.
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
9e127b6dff390d6ad5c7a0b071ae57a1d3f2485b
140
139
2015-02-23T02:47:50Z
Bpenglase
1
/* ntp.conf Configuration */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf.
We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason).
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
f32dd2dcd61292f171d509892d25db158277736f
141
140
2015-02-23T02:51:30Z
Bpenglase
1
/* Resources Used to Complete this */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf.
We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason).
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
Here's some sites I used, in no specific order. Some are referenced inline above, others are not.
* http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
* http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
* https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
* http://elinux.org/Raspberry_Pi_Kernel_Compilation
* https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md
* http://ntpi.openchaos.org/pps_pi/
* http://www.catb.org/gpsd/gpsd-time-service-howto.html
* http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
* https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
1397bb66cc5cf10686b951e9e7b69556bbbcee21
142
141
2015-02-23T03:01:29Z
Bpenglase
1
/* Intro */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it.
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf.
We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason).
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
Here's some sites I used, in no specific order. Some are referenced inline above, others are not.
* http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
* http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
* https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
* http://elinux.org/Raspberry_Pi_Kernel_Compilation
* https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md
* http://ntpi.openchaos.org/pps_pi/
* http://www.catb.org/gpsd/gpsd-time-service-howto.html
* http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
* https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
== Fin ==
== Random Notes (The building blocks) ==
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
set user password
Advanced options
-set hostname - NTP1
-Change GPU memory to 16M (not used for NTP, more memory available to the system)
-Enable Kernel i2c
-Disable Kernel/Shell over Serial
finish, reboot.
login as pi
sudo -s
set root password
Update Pi
apt-get update
apt-get dist-upgrade
rpi-update
apt-get install pps-tools snmp libcap-dev i2c-tools
Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
edit /boot/config.txt: add --
dtoverlay=pps-gpio,gpiopin=23
Custom PCB uses GPIO23
dtoverlay=i2c-rtc,ds3231
Enables the DS3231 i2c clock at boot.
reboot
Upon reboot, you should see things like this toward the end of the kernel messages:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
KERNEL TIME
Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation
Build Machine
crossdev -S -v -t arm-unknown-linux-gnueabi
export CCPREFIX=arm-unknown-linux-gnueabi-
may need gcc-config to set current version if updated
get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
mkdir modtmp
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress files
tar -cjf modules.tar.bz2 modtmp/
tar -cjf dts.tar.bz2 arch/arm/boot/dts/
Transfer Files
scp modules.tar.bz2 root@ntp1:~/
scp dts.tar.bz2 root@ntp1:~/
scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187
Extract and move modules
tar -xjf modules.tar.bz2
mv /lib/modules/<version> /lib/modules/<version>-orig
mv modtmp/lib/modules/<version> /lib/modules
cp -R modtmp/lib/firmware/* /lib/firmware
extract and move DTB's
tar -xjf dts.tar.bz2
cp arch/arm/boot/dts/*.dtb /boot/overlays
mv /boot/overlays/bcm*.dtb /boot
Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1)
grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel:
mkknlimg /boot/Image-3187 /boot/Image-3187S
grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify:
knlinfo /boot/Image-3187S
Should show something like:
./knlinfo /boot/Image-3187S
Kernel trailer found at 8697996/0x84b88c:
KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015"
DTOK: true
Edit /boot/config.txt, add:
kernel=Image-3187S
Configuring NTP
Grab latest NTP from: http://www.ntp.org/downloads.html,
extract
./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
make && make install
now wait ~20minutes
Configure network:
#Static IP
Edit /etc/networking/interfaces
iface eth0 inet static
address 10.10.10.10
netmask 255.255.255.0
gateway 10.10.10.1
rm /var/lib/ntp/ntp.conf.dhcp
GPS/UDEV Rules
create /etc/udev/rules/09-gps.rules
file contents:
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
Edit /etc/ntp.conf
enable calibrate
enable kernel
# GPS Module
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6
fudge 127.127.20.0 time2 +0.1939
# PPS of GPS Module
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/)
Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html
set timezone -
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
edit /etc/default/hwclock
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev
The RTC isn't handled by udev, so this check needs to be removed.
#http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
dpkg --purge fake-hwclock
##cd /etc/rcS.d
update-rc.d hwclock.sh enable
update-rc.d alsa-utils disable
update-rc.d x11-common disable
## OLD
apt-get install gpsd gpsd-clients python-gps
edit /etc/defaults/gpsd
start_daemon = true
devices="/dev/ttyAMA0"
flags -b -n
stty -F /dev/ttyAMA0 115200
set base_baud before gpsd starts, scans faster.
service gpsd enable
reboot, confirm with cgps -s
apt-get install libncurses5-dev bc
edit modules, include pps-gpio
Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver
Uninstall existing ntp, compile/install latest ntp
=============
-> (*) PPS Client using GPIO
Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below)
(Optional)Kernel Features -> memory split -> 2G/2G
Preemption Model -> No forced preemption (Server)
CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance
OldKernel
Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff
Note: Line numbers are different with newer kernel. Provide updated patch....
NewKernel
>=3.18.x?
Use DeviceTable - No patching
===============================
##Cross-compile NTP:
##mkdir tmpinstall##make -j2##make install
##tar -cjf ntp.tar.bz2 tmpinstall
##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin
##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
## RTC
modules/i2c already enabled in kernel from above
i2c-dev module
i2cdetect -y 1 - verify on 68
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
Add after unset TZ in hwclock.sh
modprobe i2c-bcm2708
modprobe i2c-dev
modprobe rtc-ds1307
echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device
ad3f87dedaf3c955fb940244cec03b1a3f335907
143
142
2015-02-23T03:06:52Z
Bpenglase
1
/* Random Notes (The building blocks) */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it.
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf.
We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason).
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
== Resources Used to Complete this ==
Here's some sites I used, in no specific order. Some are referenced inline above, others are not.
* http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
* http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
* https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
* http://elinux.org/Raspberry_Pi_Kernel_Compilation
* https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md
* http://ntpi.openchaos.org/pps_pi/
* http://www.catb.org/gpsd/gpsd-time-service-howto.html
* http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
* https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
== Fin ==
b97d7f277cb92b5799d906b8ec89a8fc15444d05
144
143
2015-02-23T03:21:05Z
Bpenglase
1
/* Caveats */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it.
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf.
We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason).
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
This isn't perfect by any means. Between the GPS module not being meant for timing, to the ethernet being connected over USB which introduces delays and possibly jitter. Also temperature changes affect it (both the GPS module and RTC have Temperature Compensated crystals).
There are many more precise solutions. Some of them you can even use with the Pi and modify it to be more precise.
Barring the above, it's still better than relying on your PCs built in clock!
== Resources Used to Complete this ==
Here's some sites I used, in no specific order. Some are referenced inline above, others are not.
* http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
* http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
* https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
* http://elinux.org/Raspberry_Pi_Kernel_Compilation
* https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md
* http://ntpi.openchaos.org/pps_pi/
* http://www.catb.org/gpsd/gpsd-time-service-howto.html
* http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
* https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
== Fin ==
c0b6fd508af15af6b49812a497ac20438ca39794
145
144
2015-02-23T03:25:02Z
Bpenglase
1
/* Fin */
wikitext
text/x-wiki
== Intro ==
Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :)
This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it.
Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome.
== What is this all about? ==
For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices.
This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set.
This will give me a time source on my network that is extremely accurate for my needs.
I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor])
== What does this page assume? ==
* You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output.
* You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.)
* You know how to wire/breadboard to the Pi
* Fresh install of Raspbian (either directly or through NOOBS)
====Other====
* Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v)
* Solder
* Soldering Iron
* Materials in BOM below if using custom adapter board
* Pi Case
* Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.)
* Set up a cross-compile environment. Highly recommended for recompiling the kernel.
* Comfortable compiling and installing software/kernel
== My Testing Environment ==
[[File:DevSetup.jpg|200px|thumb|left]]
* [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B]
* [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout]
* [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module]
* [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna]
* [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)]
== Physical Connections ==
The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left.
For the NavSpark Module
* Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi.
* Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi.
* Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23).
* Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi.
For the i<sup>2</sup>c RTC
* Connect pin 2, with a capacitor to the 5V power rail from the Pi.
* Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi.
* Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi.
* Connect pin 14 to a Battery, so it keeps time between power-cycles.
* Connect pin 13 to GND rail from the Pi.
Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC.
This does require soldering the components to the board.
'''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.'''
== The Code ==
You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below.
If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do.
=== Initial Setup ===
This picks up at first boot after Raspbian install.
# Set Pi User Password
# Under Advanced:
## Set Hostname: NTP1
## Change GPU Memory to 16M (Not really used, normally headless)
## Enable Kernel i<sup>2</sup>c
## Disable Kernel/Shell over Serial
# Select Finish and reboot
# Login as Pi
# sudo -s
# passwd (Set root password)
=== Update & Tools Install ===
# apt-get update
# apt-get dist-update
# rpi-update
# apt-get install pps-tools snmp libcap-dev i2c-tools
=== Add Boot Options ===
Edit /boot/config.txt, and add the following to the bottom
Enable PPS over GPIO pin 23
* dtoverlay=pps-gpio,gpiopin=23
Enable i<sup>2</sup>c RTC DS3231
* dtoverlay=i2c-rtc,ds3231
Reboot, and during the following boot, you should see something similar to:
[ 5.401032] pps_core: LinuxPPS API ver. 1 registered
[ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 5.638198] pps pps0: new PPS source pps.-1
[ 5.741468] pps pps0: Registered IRQ 417 as PPS source
[ 5.822304] bcm2708_i2c_init_pinmode(1,2)
[ 5.961135] bcm2708_i2c_init_pinmode(1,3)
[ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
To verify the HWClock:
* hwclock -r
If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly.
To verify the PPS:
* ppstest /dev/pps0
You should see output similar to
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0
source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0
source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0
source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0
If all was successful, Congrats, the system now sees the PPS and has a RTC!
=== Kernel Time ===
Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options.
It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo.
==== Cross Compiling ====
Install crossdev, if you already haven't
* emerge crossdev
Install the arm environment
* crossdev -S -v -t arm-unknown-linux-gnueabi
If you already have both of these installed, verify your build environment with gcc-config.
Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version
Export a variable to make the commands easier
* export CCPREFIX=arm-unknown-linux-gnueabi-
Grab the latest Raspberry Pi Kernel into the 'pikern' directory
* git clone --depth 1 git://github.com/raspberrypi/linux.git pikern
cd to the pikern directory for the rest of the compiling
Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config
* zcat config.gz > .config
Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
===== Configure the kernel =====
Enter the kernel's menuconfig system
* modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Change the following options
* General Setup
** Timers subsystem
*** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)"
*** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ)
* Device Drivers
** PPS Support
*** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS)
Optional, but I would also change the CPU Frequency Governor to Performance
* CPU Power Management
** CPU Frequency Scaling
*** Change "Default CPUFreq Governor" to "Performance"
*** Deselect Powersave, Userspace, Ondemand, and Conservative
Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here.
Now save and exit the menuconfig system.
===== Building the kernel =====
Now compile the kernel, and take a break (it takes a while....)
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
Once the kernel has compiled, create a temporary directory to 'install' the modules to:
* mkdir modtmp
Now 'install' the modules to that directory:
* make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install
Compress the modules for transfer to the Pi:
* tar -cjf modules.tar.bz2 modtmp
Compress the Device Tree files for transfer to the Pi:
* tar -cjf dts.tar.bz2 arch/arm/boot/dts
Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname):
* scp modules.tar.bz2 root@ntp1:~/
* scp dts.tar.bz2 root@ntp1:~/
* scp arch/arm/boot/Image root@ntp1:/boot/Image-New
===== Installing the kernel, modules, and Device Tree definitions =====
Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to.
Extract the modules
* tar -xjf modules.tar.bz2
Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+)
* mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old
Move the new modules into place
* mv modtmp/lib/modules/3.18.7+ /lib/modules
Copy firmware
* cp -R modtmp/lib/firmware/* /lib/firmware
Extract the Device Tree files
* tar -xjf dts.tar.bz2
Move the files where needed
* mv arch/arm/boot/dts/*.dtb /boot/overlays
* mv /boot/overlays/bcm*.dtb /boot
===== Kernel Trailer & Install =====
You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1].
Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg]
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg
Move the old kernel to the side
* mv /boot/kernel.img /boot/kernel-old.img
Sign the new kernel (which creates a new file, and we'll call it kernel.img!)
* perl mkknlimg /boot/Image-3187 /boot/kernel.img
Output should look like
Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015
DT: y
If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it
* wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo
* perl knlinfo /boot/kernel.img
Output shoudl look like
Kernel trailer found at 8317848/0x7eeb98:
KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015"
DTOK: true
Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname
* uname -a
Output should look like
Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux
Note the matching build times to the trailers.
If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored.
=== NTP ===
The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own!
Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p')
Download the latest source from
* http://www.ntp.org/downloads.html
I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x.
Extract (using example 4.2.8p1) & enter the directory
* tar -xzf ntp-4.2.8p1.tar.gz
* cd ntp-4.2.8p1
==== Configuring & Building NTP ====
Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl)
* ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl
This will take some time. Well over 20 minutes I believe.
Once this is done, build NTP, and install it
* make && make install
==== ntp.conf Configuration ====
Add (or adjust) the following settings to your ntp.conf.
We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason).
driftfile /var/lib/ntp/ntp.drift
enable calibrate
enable kernel
# Enable this if you want statistics to be logged.
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example
# GPS Module via NMEA
server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100
# PPS of GPS Module
server 127.127.22.0 minpoll 1 maxpoll 1
fudge 127.127.22.0 flag3 1
# Some Pool servers, from different sub-pools as well
# General NTP Pool (mainly for IPv6)
server 2.pool.ntp.org
# General US NTP Pool
server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
# Gentoo NTP Pool
server 0.gentoo.pool.ntp.org
# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
# pick a different set every time it starts up. Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 3.debian.pool.ntp.org
server 2.debian.pool.ntp.org
The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open.
Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool].
=== Networking ===
I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you.
Edit /etc/network/interfaces
Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static)
iface eth0 inet static
address 10.10.10.2
netmask 255.255.255.0
gateway 10.10.10.1
iface eth0 inet6 static
address 2001:db8::10
netmask 64
gateway 2001:db8::1
'''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf'''
=== GPS & UDev Rules ===
Edit/Create file /etc/udev/rules/09-gps.rules with the following information
# Adds symlink from serial interface to /dev/gps0 for ntpd
KERNEL=="ttyAMA0", SYMLINK+="gps0"
As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on.
=== Timezone ===
What's a good timekeeping box without the correct timezone?
Remove the existing file /etc/localtime
* rm /etc/localtime
Link in your correct timezone (I use New_York)
* ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
=== Configuring HW Clock ===
Edit /etc/default/hwclock and uncomment the following:
HWCLOCKACCESS=YES
HCTOSYS_DEVICE=rtc0
Edit /etc/init.d/hwclock.sh and make the following changes:
Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment
#i2c RTC doesn't rely on udev, so this will fail out if left in.
#if [ -d /run/udev ] || [ -d /dev/.udev ]; then
#return 0
#fi
You now have a Hardware clock, so get rid of the pesky fake hardware clock
* dpkg --purge fake-hwclock
Now enable hwclock.sh at boot
* update-rc.d hwclock.sh enable
While you're at it, disable X11-common and alsa-utils from starting. Not needed.
* update-rc.d alsa-utils disable
* update-rc.d x11-common disable
=== Finished ===
Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p
* ntpq -p
Output similar to:
remote refid st t when poll reach delay offset jitter
==============================================================================
xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635
oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004
-taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108
-blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374
-fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197
*74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333
-209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502
== Caveats ==
This isn't perfect by any means. Between the GPS module not being meant for timing, to the ethernet being connected over USB which introduces delays and possibly jitter. Also temperature changes affect it (both the GPS module and RTC have Temperature Compensated crystals).
There are many more precise solutions. Some of them you can even use with the Pi and modify it to be more precise.
Barring the above, it's still better than relying on your PCs built in clock!
== Resources Used to Complete this ==
Here's some sites I used, in no specific order. Some are referenced inline above, others are not.
* http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
* http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html
* https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi
* http://elinux.org/Raspberry_Pi_Kernel_Compilation
* https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md
* http://ntpi.openchaos.org/pps_pi/
* http://www.catb.org/gpsd/gpsd-time-service-howto.html
* http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218
* https://support.ntp.org/bin/view/Dev/Cross-compilingNTP
== Fin ==
Overall, I'm very happy with how this turned out. Granted, some things could still be done to improve upon this, and maybe over time I will do those things. I do want to do the same setup with the BeagleBone Black, and see how it compares. I also have a Soekris Net4501 that I plan to throw into the mix as well.
Also, it's another project complete, and documented! Woo!
Did I mention you should consider [http://www.pool.ntp.org/join.html joining the NTP Pool]? If you can spare some Internets, I highly recommend it.
59126b309b2b4816ea1b8a515634c8112e145dde
File:DevSetup.jpg
6
19
107
2014-10-22T01:41:40Z
Bpenglase
1
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Computer Related Prodding
0
3
146
7
2015-03-05T04:05:12Z
Bpenglase
1
wikitext
text/x-wiki
* [[The World According to Apple]] - Ways I have found to get OS X/iOS to function in the "Enterprise" world, typically with 3rd party software.
* Breaking Windows - Different things I have found building Windows images and supporting Windows machines
* [[Linux Things]] - Stuff being done in/with Linux (typically Gentoo).
129031394829eb3f9a6b0790c360b5ac4840dcb7
Linux Things
0
20
147
2015-03-05T04:06:09Z
Bpenglase
1
Created page with "[[KVM/QEMU on Gentoo with Open vSwitch]]"
wikitext
text/x-wiki
[[KVM/QEMU on Gentoo with Open vSwitch]]
2c92f2201f547d006ef02a474dec96da6bdaa165
KVM/QEMU on Gentoo with Open vSwitch
0
21
148
2015-03-05T04:07:38Z
Bpenglase
1
Created page with "https://bbs.archlinux.org/viewtopic.php?id=179604 http://www.siliconloons.com/virtual-machines-on-fedora-17-with-open-vswitch/ http://www.siliconloons.com/fedora-17-with-open-..."
wikitext
text/x-wiki
https://bbs.archlinux.org/viewtopic.php?id=179604
http://www.siliconloons.com/virtual-machines-on-fedora-17-with-open-vswitch/
http://www.siliconloons.com/fedora-17-with-open-vswitch/
http://wiki.gentoo.org/wiki/QEMU_with_Open_vSwitch_network
http://blog.scottlowe.org/2012/11/07/using-vlans-with-ovs-and-libvirt/
http://ronnybull.com/2013/11/25/open-vswitch-on-gentoo-setting-up-your-first-vswitch/
http://libvirt.org/drvqemu.html
http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf
8efc5951f80b232963c789b99a76bd28f54323fe
Network & Systems Wrangling
0
6
149
74
2015-05-11T15:32:32Z
Bpenglase
1
wikitext
text/x-wiki
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
* [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
* [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
* [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics.
* [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu.
* [[Installing Windows over a Network]] - Installing Windows 7 Pro over the network, using iPXE, WIMBoot, and Samba.
* [[Multicast Setup]] - Enabling Multicast on Cisco 3750 and 4500X to allow cross-subnet/building Video Transmission.
1618d3b8e9decde9b12ca9e19353d97d5b8afbb8
Multicast Setup
0
22
150
2015-05-11T15:42:11Z
Bpenglase
1
Initial - Throwing links out.
wikitext
text/x-wiki
** http://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/rps.html#wp1029241
** http://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/rps.html
** http://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst3750/software/release/12-2_37_se/configuration/guide/scg/swmcast.html
** http://www.cisco.com/c/en/us/support/docs/switches/catalyst-3750-series-switches/98289-pim-stub.html
** http://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/rps.html#wp1029241
** http://www.cisco.com/c/en/us/td/docs/ios/12_2/ip/configuration/guide/fipr_c/1cfmulti.html#wp1001103
** http://nostringsattachedshow.com/2012/01/16/so-you-want-to-play-with-multicast-part-1/
** http://www.cisco.com/c/en/us/support/docs/ip/ip-multicast/9356-48.html
ee37749f72c58d6c057915e3999f5b35ffd1be1f
Network & Systems Wrangling
0
6
151
149
2016-09-02T20:20:13Z
Bpenglase
1
Added link for Supermicro 2028R-DE2CR24L
wikitext
text/x-wiki
* [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication).
* [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment.
* [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment.
* [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics.
* [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu.
* [[Installing Windows over a Network]] - Installing Windows 7 Pro over the network, using iPXE, WIMBoot, and Samba.
* [[Multicast Setup]] - Enabling Multicast on Cisco 3750 and 4500X to allow cross-subnet/building Video Transmission.
* [[Deploying a SuperMicro SuperStorage 2028R-DE2CR24L]] -- Setting up the 2028R-DE2CR24L for Windows Storage Spaces as a iSCSI SAN for VMware ESXi
b165da160d4740dbbd48048bf15f4f201d92b6f1
Deploying a SuperMicro SuperStorage 2028R-DE2CR24L
0
23
152
2016-09-02T20:44:37Z
Bpenglase
1
Initial page create and save.
wikitext
text/x-wiki
https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm
Quick Specs as ours is configured:
4x: Intel Xeon E5-2603 V4 (2 per node)
16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each)
2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node)
4x: MICRON 800GB S630DC 2.5" SAS
10x: SEAGATE 1.2TB SAS 10K PRM 51
2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node)
Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf
Block Diagram located on page 12.
Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat
PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717.
Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default)
System power redundancy provided at 240V only.
Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core).
fa37aed8bfadec6813ddc1ca06af4b1a08ad2ba8
153
152
2016-09-03T21:46:56Z
Bpenglase
1
wikitext
text/x-wiki
https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm
Quick Specs as ours is configured:
4x: Intel Xeon E5-2603 V4 (2 per node)
16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each)
2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node)
4x: MICRON 800GB S630DC 2.5" SAS
10x: SEAGATE 1.2TB SAS 10K PRM 51
2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node)
Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf
Block Diagram located on page 12.
Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat
PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717.
Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default)
System power redundancy provided at 240V only.
Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core).
Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/
Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression
712521a7106756d73a11e196d70babfbfb2fb20c
154
153
2016-09-04T04:32:17Z
Bpenglase
1
wikitext
text/x-wiki
https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm
Quick Specs as ours is configured:
4x: Intel Xeon E5-2603 V4 (2 per node)
16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each)
2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node)
4x: MICRON 800GB S630DC 2.5" SAS
10x: SEAGATE 1.2TB SAS 10K PRM 51
2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node)
Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf
Block Diagram located on page 12.
Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat
PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717.
Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default)
System power redundancy provided at 240V only.
Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core).
Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/
Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression
For iSCSI Failover Target Role, Delegate cluster to OU: http://morgansimonsen.com/2013/12/17/delegating-computer-object-management-tasks-2/
9170dbd330213c6bd8953c4fbaaba2011771e88c
155
154
2016-09-05T01:10:09Z
Bpenglase
1
wikitext
text/x-wiki
https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm
Quick Specs as ours is configured:
4x: Intel Xeon E5-2603 V4 (2 per node)
16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each)
2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node)
4x: MICRON 800GB S630DC 2.5" SAS
10x: SEAGATE 1.2TB SAS 10K PRM 51
2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node)
Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf
Block Diagram located on page 12.
Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat
PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717.
Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default)
System power redundancy provided at 240V only.
Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core).
Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/
Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression
For iSCSI Failover Target Role, Delegate cluster to OU: http://morgansimonsen.com/2013/12/17/delegating-computer-object-management-tasks-2/
Replace failed disk: https://technet.microsoft.com/en-us/library/dn782852(v=ws.11).aspx
80af9ff0863dd44241e86fd1cc4bcd26cf15b87a
156
155
2016-09-06T17:54:42Z
Bpenglase
1
wikitext
text/x-wiki
https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm
Quick Specs as ours is configured:
4x: Intel Xeon E5-2603 V4 (2 per node)
16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each)
2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node)
4x: MICRON 800GB S630DC 2.5" SAS
10x: SEAGATE 1.2TB SAS 10K PRM 51
2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node)
Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf
Block Diagram located on page 12.
Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat
PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717.
Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default)
System power redundancy provided at 240V only.
Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core).
Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/
Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression
For iSCSI Failover Target Role, Delegate cluster to OU: http://morgansimonsen.com/2013/12/17/delegating-computer-object-management-tasks-2/
Replace failed disk: https://technet.microsoft.com/en-us/library/dn782852(v=ws.11).aspx
Enable iSCSI in Firewall.
f8caebf5ec1a80a984d3391de91711fc97e44f16
Main Page
0
1
157
6
2017-07-08T20:37:58Z
Bpenglase
1
Added Amateur Radio section
wikitext
text/x-wiki
''' Welcome. '''
Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work.
* [[Computer Related Prodding]]
* [[Network & Systems Wrangling]]
* [[Dabbling in Electronics]]
* [[Amateur Radio Meddling]]
d68cf7307f285e552e54343d50587ef8ffbd897f
159
157
2022-05-28T01:10:34Z
Bpenglase
1
Added HA
wikitext
text/x-wiki
''' Welcome. '''
Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work.
* [[Computer Related Prodding]]
* [[Network & Systems Wrangling]]
* [[Dabbling in Electronics]]
* [[Amateur Radio Meddling]]
* [[Home Automation]]
c1b6e582be56cb9caf4690c65a90a04c6f5ab201
Amateur Radio Meddling
0
24
158
2017-07-08T20:38:42Z
Bpenglase
1
Initial!
wikitext
text/x-wiki
The place where I'll eventually post stuff related to Amateur Radio...
3d3db6fd19f06b3fd30792b5c291bcc40e1766ce
Home Automation
0
25
160
2022-05-28T01:13:59Z
Bpenglase
1
Created page with "== Random Notes == Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US. This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncommen..."
wikitext
text/x-wiki
== Random Notes ==
Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US.
This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267
However you actually need to install the Gecko v3.2 SDK
Firmware as of writing: C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.2\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7.16.3_297_EFR32ZG14_REGION_US.gbl
Is then able to be written with the PC Controller.
7170771a136fc431ce150dfb5338d2ecbd33d347
161
160
2022-05-28T01:14:15Z
Bpenglase
1
wikitext
text/x-wiki
== Random Notes ==
Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US.
This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267
However you actually need to install the Gecko v3.2 SDK
Firmware as of writing: C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.2\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7.16.3_297_EFR32ZG14_REGION_US.gbl
Is then able to be written with the PC Controller.
61daf3a3023f824b9556766771fd084341536f55
162
161
2022-05-28T02:24:10Z
Bpenglase
1
wikitext
text/x-wiki
== Random Notes ==
Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US.
This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267
More info here: https://github.com/kpine/zwave-js-server-docker/wiki/700-series-Controller-Firmware-Updates-(Linux)
However you actually need to install the "Gecko SDK - 32bit and Wireless MCUs" (which at this time was 4.0.2)
Firmware as of writing: C:\Users\<your windows user here>\SimplicityStudio\SDKs\gecko_sdk\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7_17_2_406_EFR32ZG14_REGION_US.gbl
Is then able to be written with the PC Controller.
d59b5b6852597a2da7b73edac837ddd2a89ea89c
163
162
2022-05-28T02:26:22Z
Bpenglase
1
wikitext
text/x-wiki
== Random Notes ==
Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US.
<s>This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267</s>
More info here: https://github.com/kpine/zwave-js-server-docker/wiki/700-series-Controller-Firmware-Updates-(Linux)
However you actually need to install the "Gecko SDK - 32bit and Wireless MCUs" (which at this time was 4.0.2)
Firmware as of writing: C:\Users\<your windows user here>\SimplicityStudio\SDKs\gecko_sdk\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7_17_2_406_EFR32ZG14_REGION_US.gbl
Is then able to be written with the PC Controller.
38242af2c18a3a1fde08736427a09d40a0f74f35